package com.muyu.system.controller;

import com.muyu.common.core.domain.Result;
import com.muyu.common.core.utils.StringUtils;
import com.muyu.common.core.utils.poi.ExcelUtil;
import com.muyu.common.core.web.controller.BaseController;
import com.muyu.common.core.web.page.TableDataInfo;
import com.muyu.common.security.annotation.RequiresPermissions;
import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.common.system.domain.SysDept;
import com.muyu.common.system.domain.SysEnt;
import com.muyu.common.system.domain.SysRole;
import com.muyu.common.system.domain.SysUser;
import com.muyu.system.domain.SysFirm;
import com.muyu.system.domain.SysMenu;
import com.muyu.system.domain.req.SysFirmReq;
import com.muyu.system.service.ISysFirmService;
import com.muyu.system.service.SysEntService;
import com.muyu.system.service.impl.SysConfigServiceImpl;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 企业基础信息Controller
 *
 * @author muyu
 * @date 2024-09-18
 */
@RestController
@RequestMapping("/firmInfo")
public class SysFirmController extends BaseController
{
    @Resource
    private ISysFirmService sysFirmService;
    @Resource
    private SysEntService sysEntService;
    @Resource
    private SysRoleController sysRoleController;
    @Resource
    private SysMenuController sysMenuController;
    @Resource
    private SysUserController sysUserController;
    @Resource
    private SysDeptController sysDeptController;


    private static final String FIRM_CREDIT_CODE = "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$";
    @Autowired
    private SysConfigServiceImpl sysConfigServiceImpl;

    /**
     * 查询企业基础信息列表
     */
    @RequiresPermissions("firm:firmInfo:list")
    @GetMapping("/list")
    public Result<TableDataInfo<SysFirm>> list(SysFirm sysFirm)
    {
        startPage();
        List<SysFirm> list = sysFirmService.selectSysFirmList(sysFirm);
        return getDataTable(list);
    }

    /**
     * 导出企业基础信息列表
     */
    @RequiresPermissions("firm:firmInfo:export")
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysFirm sysFirm)
    {
        List<SysFirm> list = sysFirmService.selectSysFirmList(sysFirm);
        ExcelUtil<SysFirm> util = new ExcelUtil<SysFirm>(SysFirm.class);
        util.exportExcel(response, list, "企业基础信息数据");
    }

    /**
     * 获取企业基础信息详细信息
     */
    @RequiresPermissions("firm:firmInfo:query")
    @GetMapping(value = "/{id}")
    public Result<List<SysFirm>> getInfo(@PathVariable("id") Long id)
    {
        return success(sysFirmService.selectSysFirmById(id));
    }

    /**
     * 新增企业基础信息
     */
    @RequiresPermissions("firm:firmInfo:add")
    @PostMapping
    public Result<Integer> add(@Validated @RequestBody SysFirmReq sysFirm) {
        String firmName = sysFirm.getFirmName();
        String firmCode = sysFirm.getFirmCode();
        String firmCreditCode = sysFirm.getFirmCreditCode();

        // 验证企业基础信息是否为空
        if (StringUtils.isAllBlank(firmName, firmCode, firmCreditCode)) {
            return error("新增 企业基础信息 '" + sysFirm + "'失败，企业基础信息信息为空");
        }

        // 检查企业基础信息是否已存在
        if (sysFirmService.checkIdUnique(sysFirm)) {
            return error("新增 企业基础信息 '" + sysFirm + "'失败，企业基础信息已存在");
        }

        // 验证统一社会信用代码格式
        if (!isValidFirmCreditCode(firmCreditCode)) {
            return error("新增 企业基础信息 '" + sysFirm + "'失败，统一社会信用代码格式不正确");
        }

        //添加部门
        SysDept sysDept = new SysDept();
        sysDept.setFirmCode(firmCode);
        sysDept.setParentId(100L);
        sysDept.setDeptName(firmName);
        sysDept.setAncestors("0,100");
        sysDept.setOrderNum(3);
        sysDept.setStatus("0");
        sysDept.setDelFlag("0");

        sysDeptController.add(sysDept);

        // 设置创建者和状态
        sysFirm.setCreateBy(SecurityUtils.getUsername());

        //添加用户与用户角色
        SysUser sysUser = new SysUser();
        sysUser.setFirmCode(firmCode);
        sysUser.setUserName(sysFirm.getFirmCode()+"-admin");
        sysUser.setNickName(sysFirm.getFirmName()+"管理员");
        sysUser.setPassword(sysConfigServiceImpl.selectConfigByKey("sys.user.initPassword"));
        sysUser.setDeptId(sysDept.getDeptId());
        sysUser.setRoleIds(new Long[]{119L});
        sysUserController.add(sysUser);

        // 创建数据库和表
        try {
            createDatabaseAndTables(firmCode);
        } catch (SQLException e) {
            return error("数据库操作失败: " + e.getMessage());
        }

        // 保存企业信息
        SysEnt sysEnt = new SysEnt();
        sysEnt.setUserName("root");
        sysEnt.setPassword("bawei2112A");
        sysEnt.setEntCode(firmCode);
        sysEnt.setDbName(firmCode);
        sysEnt.setIp("47.116.173.119");
        sysEnt.setPort(3306);
        sysEntService.save(sysEnt);

        sysFirm.setMemberId(1L);

        return toAjax(sysFirmService.save(sysFirm));
    }

    //
    private boolean isValidFirmCreditCode(String firmCreditCode) {
        Pattern pattern = Pattern.compile(FIRM_CREDIT_CODE);
        Matcher matcher = pattern.matcher(firmCreditCode);
        return matcher.matches();
    }

    private void createDatabaseAndTables(String firmCode) throws SQLException {
        String url = "jdbc:mysql://47.116.173.119:3306/?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
        try (Connection connection = DriverManager.getConnection(url, "root", "bawei2112A");
             Statement statement = connection.createStatement()) {

            // 创建数据库
            statement.executeUpdate("CREATE DATABASE IF NOT EXISTS " + firmCode);
        }

        // 切换到新的数据库连接
        Connection connection = null;
        try {
            url = "jdbc:mysql://47.116.173.119:3306/" + firmCode + "?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
            String user = "root";
            String pwd = "bawei2112A";
            String driverClassName = "com.mysql.cj.jdbc.Driver";
            Class.forName(driverClassName);
            connection = DriverManager.getConnection(url, user, pwd);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        ClassPathResource rc = new ClassPathResource("static/saas_operation.sql");
        EncodedResource er = new EncodedResource(rc, "utf-8");
        ScriptUtils.executeSqlScript(connection, er);

    }


    /**
     * 修改企业基础信息
     */
    @RequiresPermissions("firm:firmInfo:edit")
    @PutMapping
    public Result<Integer> edit(
            @Validated @RequestBody SysFirm sysFirm)
    {
        if (!sysFirmService.checkIdUnique(sysFirm)) {
            return error("修改 企业基础信息 '" + sysFirm + "'失败，企业基础信息不存在");
        }
        sysFirm.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(sysFirmService.updateById(sysFirm));
    }

    /**
     * 删除企业基础信息
     */
    @RequiresPermissions("firm:firmInfo:remove")
    @DeleteMapping("/{ids}")
    public Result<Integer> remove(@PathVariable("ids") Long[] ids)
    {
        sysFirmService.removeBatchByIds(Arrays.asList(ids));
        return success();
    }

}
