package com.writeoff.module.system.service;

import com.writeoff.common.api.PageResult;
import com.writeoff.common.exception.BusinessException;
import com.writeoff.module.file.service.OssService;
import com.writeoff.module.system.dto.CreateEnterpriseRequest;
import com.writeoff.module.system.dto.UpdateEnterpriseRequest;
import com.writeoff.module.system.model.EnterpriseInfo;
import com.writeoff.security.AuthContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class EnterpriseService {
    private final JdbcTemplate jdbcTemplate;
    private final OssService ossService;

    private static final RowMapper<EnterpriseInfo> ENTERPRISE_ROW_MAPPER = (rs, n) -> new EnterpriseInfo(
            rs.getLong("id"),
            rs.getString("enterprise_name"),
            rs.getString("enterprise_url"),
            rs.getString("logo_url"),
            rs.getString("status"),
            rs.getString("created_at")
    );

    public EnterpriseService(JdbcTemplate jdbcTemplate, OssService ossService) {
        this.jdbcTemplate = jdbcTemplate;
        this.ossService = ossService;
    }

    public PageResult<EnterpriseInfo> list(int pageNo, int pageSize) {
        int safePage = Math.max(pageNo, 1);
        int safeSize = Math.min(Math.max(pageSize, 1), 100);
        int offset = (safePage - 1) * safeSize;

        Integer total = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM enterprise WHERE tenant_id=? AND is_deleted=0",
                Integer.class,
                tenantId()
        );
        long totalCount = total == null ? 0 : total;

        List<EnterpriseInfo> list = jdbcTemplate.query(
                "SELECT id, enterprise_name, enterprise_url, logo_url, status, " +
                        "DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') AS created_at " +
                        "FROM enterprise WHERE tenant_id=? AND is_deleted=0 ORDER BY id DESC LIMIT ? OFFSET ?",
                ENTERPRISE_ROW_MAPPER,
                tenantId(),
                safeSize,
                offset
        );
        return new PageResult<EnterpriseInfo>(list, totalCount, safePage, safeSize);
    }

    public EnterpriseInfo create(CreateEnterpriseRequest request) {
        String name = request.getEnterpriseName().trim();
        Integer exists = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM enterprise WHERE tenant_id=? AND enterprise_name=? AND is_deleted=0",
                Integer.class,
                tenantId(),
                name
        );
        if (exists != null && exists > 0) {
            throw new BusinessException(10001, "企业名称已存在");
        }
        jdbcTemplate.update(
                "INSERT INTO enterprise (tenant_id, enterprise_name, enterprise_url, logo_url, status, is_deleted, created_by, updated_by) " +
                        "VALUES (?, ?, ?, ?, 'ENABLED', 0, ?, ?)",
                tenantId(),
                name,
                normalizeNullable(request.getEnterpriseUrl()),
                normalizeNullable(request.getLogoUrl()),
                safeUserId(),
                safeUserId()
        );
        Long id = jdbcTemplate.queryForObject("SELECT IFNULL(MAX(id), 0) FROM enterprise WHERE tenant_id=?", Long.class, tenantId());
        return findById(id == null ? 0L : id);
    }

    public EnterpriseInfo update(Long id, UpdateEnterpriseRequest request) {
        assertExists(id);
        String name = request.getEnterpriseName().trim();
        Integer dup = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM enterprise WHERE tenant_id=? AND enterprise_name=? AND id<>? AND is_deleted=0",
                Integer.class,
                tenantId(),
                name,
                id
        );
        if (dup != null && dup > 0) {
            throw new BusinessException(10001, "企业名称已存在");
        }
        jdbcTemplate.update(
                "UPDATE enterprise SET enterprise_name=?, enterprise_url=?, logo_url=?, updated_by=?, updated_at=CURRENT_TIMESTAMP " +
                        "WHERE tenant_id=? AND id=?",
                name,
                normalizeNullable(request.getEnterpriseUrl()),
                normalizeNullable(request.getLogoUrl()),
                safeUserId(),
                tenantId(),
                id
        );
        return findById(id);
    }

    public void enable(Long id) {
        assertExists(id);
        jdbcTemplate.update(
                "UPDATE enterprise SET status='ENABLED', updated_by=?, updated_at=CURRENT_TIMESTAMP WHERE tenant_id=? AND id=?",
                safeUserId(),
                tenantId(),
                id
        );
    }

    public void disable(Long id) {
        assertExists(id);
        jdbcTemplate.update(
                "UPDATE enterprise SET status='DISABLED', updated_by=?, updated_at=CURRENT_TIMESTAMP WHERE tenant_id=? AND id=?",
                safeUserId(),
                tenantId(),
                id
        );
    }

    public void softDelete(Long id) {
        assertExists(id);
        // 检查是否有活跃项目关联
        Integer activeProjects = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM project WHERE tenant_id=? AND partner_enterprise_id=? AND is_deleted=0 AND status NOT IN ('ARCHIVED', 'TERMINATED')",
                Integer.class,
                tenantId(),
                id
        );
        if (activeProjects != null && activeProjects > 0) {
            throw new BusinessException(10001, "该企业下存在活跃项目，请先归档相关项目后再删除");
        }
        jdbcTemplate.update(
                "UPDATE enterprise SET is_deleted=1, status='DISABLED', updated_by=?, updated_at=CURRENT_TIMESTAMP WHERE tenant_id=? AND id=?",
                safeUserId(),
                tenantId(),
                id
        );
    }

    public void assertEnabled(Long enterpriseId) {
        if (enterpriseId == null) {
            return;
        }
        Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM enterprise WHERE tenant_id=? AND id=? AND is_deleted=0 AND status='ENABLED'",
                Integer.class,
                tenantId(),
                enterpriseId
        );
        if (count == null || count == 0) {
            throw new BusinessException(10003, "企业不存在或已停用");
        }
    }

    public Map<String, Object> presignLogoUpload(String fileName, String contentType) {
        String name = fileName == null ? "" : fileName.trim();
        if (name.isEmpty()) {
            throw new BusinessException(10001, "文件名不能为空");
        }
        String ext = "";
        int idx = name.lastIndexOf('.');
        if (idx > 0 && idx < name.length() - 1) {
            ext = "." + name.substring(idx + 1).toLowerCase();
        }
        String normalizedContentType = normalizeContentType(contentType);
        String objectKey = "enterprise/logo/" + tenantId() + "/" + safeUserId() + "/" + UUID.randomUUID().toString().replace("-", "") + ext;
        String uploadUrl = ossService.generateUploadUrl(objectKey, normalizedContentType);
        Map<String, Object> data = new LinkedHashMap<String, Object>();
        data.put("objectKey", objectKey);
        data.put("uploadUrl", uploadUrl);
        data.put("contentType", normalizedContentType);
        data.put("method", "PUT");
        return data;
    }

    private EnterpriseInfo findById(Long id) {
        List<EnterpriseInfo> list = jdbcTemplate.query(
                "SELECT id, enterprise_name, enterprise_url, logo_url, status, " +
                        "DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') AS created_at " +
                        "FROM enterprise WHERE tenant_id=? AND id=? AND is_deleted=0",
                ENTERPRISE_ROW_MAPPER,
                tenantId(),
                id
        );
        if (list.isEmpty()) {
            throw new BusinessException(10003, "企业不存在");
        }
        return list.get(0);
    }

    private void assertExists(Long id) {
        Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM enterprise WHERE tenant_id=? AND id=? AND is_deleted=0",
                Integer.class,
                tenantId(),
                id
        );
        if (count == null || count == 0) {
            throw new BusinessException(10003, "企业不存在");
        }
    }

    private String normalizeNullable(String value) {
        if (value == null) {
            return null;
        }
        String trimmed = value.trim();
        return trimmed.isEmpty() ? null : trimmed;
    }

    private String normalizeContentType(String contentType) {
        if (contentType == null || contentType.trim().isEmpty()) {
            return "application/octet-stream";
        }
        return contentType.trim();
    }

    private Long tenantId() {
        return AuthContext.requireTenantId();
    }

    private Long safeUserId() {
        Long userId = AuthContext.userId();
        return userId == null ? 0L : userId;
    }
}
