package com.erp.supplier.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.supplier.dto.request.*;
import com.erp.supplier.dto.response.*;
import com.erp.supplier.entity.*;
import com.erp.supplier.exception.SupplierException;
import com.erp.supplier.exception.SupplierNotFoundException;
import com.erp.supplier.repository.*;
import com.erp.supplier.service.SupplierService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import com.erp.common.core.model.PageResponse;

@Slf4j
@Service
@RequiredArgsConstructor
public class SupplierServiceImpl implements SupplierService {

    private final SupplierRepository supplierRepository;
    private final SupplierContactRepository contactRepository;
    private final SupplierBankAccountRepository bankAccountRepository;
    private final SupplierRatingRepository ratingRepository;
    private final ProcurementInquiryRepository inquiryRepository;
    private final SupplierOperationLogRepository operationLogRepository;
    private final ObjectMapper objectMapper;

    @Value("${supplier.code.prefix:S}")
    private String codePrefix;

    // ============ 供应商基础管理 ============

    @Override
    public PageResponse<SupplierResponse> listSuppliers(SupplierQueryRequest request) {
        Page<Supplier> page = new Page<>(request.getPage(), request.getLimit());

        LocalDateTime startDate = null;
        LocalDateTime endDate = null;
        if (StringUtils.hasText(request.getStartDate())) {
            startDate = LocalDate.parse(request.getStartDate()).atStartOfDay();
        }
        if (StringUtils.hasText(request.getEndDate())) {
            endDate = LocalDate.parse(request.getEndDate()).atTime(23, 59, 59);
        }

        IPage<Supplier> supplierPage = supplierRepository.selectSupplierPage(
                page, request.getStatus(), request.getGrade(),
                request.getSupplierType(), request.getIndustry(),
                request.getKeyword(), startDate, endDate);

        List<SupplierResponse> list = supplierPage.getRecords().stream()
                .map(SupplierResponse::fromEntity)
                .collect(Collectors.toList());

        return PageResponse.of(list, supplierPage.getTotal(),
                (int) supplierPage.getCurrent(), request.getLimit());
    }

    @Override
    public SupplierResponse getSupplier(Long id) {
        Supplier supplier = supplierRepository.selectById(id);
        if (supplier == null) {
            throw new SupplierNotFoundException("供应商不存在: " + id);
        }
        return enrichSupplierResponse(SupplierResponse.fromEntity(supplier), id);
    }

    @Override
    @Transactional
    public SupplierResponse createSupplier(SupplierCreateRequest request, OperatorInfo operator) {
        String supplierCode = generateSupplierCode();

        Supplier supplier = Supplier.builder()
                .supplierCode(supplierCode)
                .supplierName(request.getSupplierName())
                .supplierType(request.getSupplierType())
                .industry(request.getIndustry())
                .businessLicense(request.getBusinessLicense())
                .registeredCapital(request.getRegisteredCapital())
                .establishmentDate(request.getEstablishmentDate())
                .legalPerson(request.getLegalPerson())
                .phone(request.getPhone())
                .email(request.getEmail())
                .website(request.getWebsite())
                .province(request.getProvince())
                .city(request.getCity())
                .district(request.getDistrict())
                .address(request.getAddress())
                .mainBusiness(request.getMainBusiness())
                .status(request.getStatus() != null ? request.getStatus() : "pending")
                .grade(request.getGrade() != null ? request.getGrade() : "C")
                .creditScore(request.getCreditScore() != null ? request.getCreditScore() : 60)
                .isInternal(request.getIsInternal() != null ? request.getIsInternal() : 0)
                .cooperationStartDate(request.getCooperationStartDate())
                .cooperationEndDate(request.getCooperationEndDate())
                .settlementMethod(request.getSettlementMethod())
                .paymentDays(request.getPaymentDays())
                .minimumOrderQuantity(request.getMinimumOrderQuantity())
                .remark(request.getRemark())
                .attachments(request.getAttachments())
                .auditStatus("pending")
                .build();

        supplierRepository.insert(supplier);

        saveOperationLog(supplier.getId(), operator, "create", "创建供应商",
                null, objectMapper.valueToTree(supplier).toString());

        return enrichSupplierResponse(SupplierResponse.fromEntity(supplier), supplier.getId());
    }

    @Override
    @Transactional
    public SupplierResponse updateSupplier(Long id, SupplierUpdateRequest request, OperatorInfo operator) {
        Supplier supplier = supplierRepository.selectById(id);
        if (supplier == null) {
            throw new SupplierNotFoundException("供应商不存在: " + id);
        }

        String beforeData = objectMapper.valueToTree(supplier).toString();

        if (StringUtils.hasText(request.getSupplierName())) supplier.setSupplierName(request.getSupplierName());
        if (StringUtils.hasText(request.getSupplierType())) supplier.setSupplierType(request.getSupplierType());
        if (StringUtils.hasText(request.getIndustry())) supplier.setIndustry(request.getIndustry());
        if (StringUtils.hasText(request.getBusinessLicense())) supplier.setBusinessLicense(request.getBusinessLicense());
        if (request.getRegisteredCapital() != null) supplier.setRegisteredCapital(request.getRegisteredCapital());
        if (StringUtils.hasText(request.getEstablishmentDate())) supplier.setEstablishmentDate(request.getEstablishmentDate());
        if (StringUtils.hasText(request.getLegalPerson())) supplier.setLegalPerson(request.getLegalPerson());
        if (StringUtils.hasText(request.getPhone())) supplier.setPhone(request.getPhone());
        if (StringUtils.hasText(request.getEmail())) supplier.setEmail(request.getEmail());
        if (StringUtils.hasText(request.getWebsite())) supplier.setWebsite(request.getWebsite());
        if (StringUtils.hasText(request.getProvince())) supplier.setProvince(request.getProvince());
        if (StringUtils.hasText(request.getCity())) supplier.setCity(request.getCity());
        if (StringUtils.hasText(request.getDistrict())) supplier.setDistrict(request.getDistrict());
        if (StringUtils.hasText(request.getAddress())) supplier.setAddress(request.getAddress());
        if (StringUtils.hasText(request.getMainBusiness())) supplier.setMainBusiness(request.getMainBusiness());
        if (StringUtils.hasText(request.getStatus())) supplier.setStatus(request.getStatus());
        if (StringUtils.hasText(request.getGrade())) supplier.setGrade(request.getGrade());
        if (request.getCreditScore() != null) supplier.setCreditScore(request.getCreditScore());
        if (request.getIsInternal() != null) supplier.setIsInternal(request.getIsInternal());
        if (StringUtils.hasText(request.getCooperationStartDate())) supplier.setCooperationStartDate(request.getCooperationStartDate());
        if (StringUtils.hasText(request.getCooperationEndDate())) supplier.setCooperationEndDate(request.getCooperationEndDate());
        if (StringUtils.hasText(request.getSettlementMethod())) supplier.setSettlementMethod(request.getSettlementMethod());
        if (request.getPaymentDays() != null) supplier.setPaymentDays(request.getPaymentDays());
        if (request.getMinimumOrderQuantity() != null) supplier.setMinimumOrderQuantity(request.getMinimumOrderQuantity());
        if (StringUtils.hasText(request.getRemark())) supplier.setRemark(request.getRemark());
        if (StringUtils.hasText(request.getAttachments())) supplier.setAttachments(request.getAttachments());

        supplierRepository.updateById(supplier);

        saveOperationLog(supplier.getId(), operator, "update", "更新供应商",
                beforeData, objectMapper.valueToTree(supplier).toString());

        return enrichSupplierResponse(SupplierResponse.fromEntity(supplier), supplier.getId());
    }

    @Override
    @Transactional
    public void deleteSupplier(Long id, OperatorInfo operator) {
        Supplier supplier = supplierRepository.selectById(id);
        if (supplier == null) {
            throw new SupplierNotFoundException("供应商不存在: " + id);
        }
        supplierRepository.deleteById(id);
        saveOperationLog(id, operator, "delete", "删除供应商",
                objectMapper.valueToTree(supplier).toString(), null);
    }

    @Override
    @Transactional
    public SupplierResponse auditSupplier(Long id, SupplierAuditRequest request, OperatorInfo operator) {
        Supplier supplier = supplierRepository.selectById(id);
        if (supplier == null) {
            throw new SupplierNotFoundException("供应商不存在: " + id);
        }

        String beforeData = objectMapper.valueToTree(supplier).toString();

        if ("approve".equals(request.getAction())) {
            supplier.setAuditStatus("approved");
            supplier.setStatus("active");
        } else if ("reject".equals(request.getAction())) {
            supplier.setAuditStatus("rejected");
            supplier.setStatus("inactive");
        } else {
            throw new SupplierException("不支持的审核操作: " + request.getAction());
        }

        supplier.setAuditComment(request.getComment());
        supplier.setAuditorId(operator.getOperatorId());
        supplier.setAuditTime(LocalDateTime.now());

        supplierRepository.updateById(supplier);

        saveOperationLog(supplier.getId(), operator,
                "approve".equals(request.getAction()) ? "audit_approve" : "audit_reject",
                "approve".equals(request.getAction()) ? "审核通过" : "审核驳回",
                beforeData, objectMapper.valueToTree(supplier).toString());

        return enrichSupplierResponse(SupplierResponse.fromEntity(supplier), supplier.getId());
    }

    // ============ 供应商联系人管理 ============

    @Override
    public List<SupplierContactResponse> listContacts(Long supplierId) {
        verifySupplierExists(supplierId);
        return contactRepository.selectBySupplierId(supplierId).stream()
                .map(SupplierContactResponse::fromEntity)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public SupplierContactResponse createContact(Long supplierId, SupplierContactCreateRequest request, OperatorInfo operator) {
        verifySupplierExists(supplierId);

        SupplierContact contact = SupplierContact.builder()
                .supplierId(supplierId)
                .contactName(request.getContactName())
                .gender(request.getGender())
                .department(request.getDepartment())
                .position(request.getPosition())
                .mobile(request.getMobile())
                .phone(request.getPhone())
                .email(request.getEmail())
                .qq(request.getQq())
                .wechat(request.getWechat())
                .isPrimary(request.getIsPrimary() != null ? request.getIsPrimary() : 0)
                .isEmergency(request.getIsEmergency() != null ? request.getIsEmergency() : 0)
                .remark(request.getRemark())
                .build();

        contactRepository.insert(contact);

        if (contact.getIsPrimary() != null && contact.getIsPrimary() == 1) {
            clearPrimaryContact(supplierId, contact.getId());
        }

        saveOperationLog(supplierId, operator, "create_contact", "添加联系人: " + request.getContactName(),
                null, objectMapper.valueToTree(contact).toString());

        return SupplierContactResponse.fromEntity(contact);
    }

    @Override
    @Transactional
    public SupplierContactResponse updateContact(Long supplierId, Long contactId, SupplierContactUpdateRequest request, OperatorInfo operator) {
        verifySupplierExists(supplierId);

        SupplierContact contact = contactRepository.selectById(contactId);
        if (contact == null || !contact.getSupplierId().equals(supplierId)) {
            throw new SupplierNotFoundException("联系人不存在: " + contactId);
        }

        String beforeData = objectMapper.valueToTree(contact).toString();

        if (StringUtils.hasText(request.getContactName())) contact.setContactName(request.getContactName());
        if (StringUtils.hasText(request.getGender())) contact.setGender(request.getGender());
        if (StringUtils.hasText(request.getDepartment())) contact.setDepartment(request.getDepartment());
        if (StringUtils.hasText(request.getPosition())) contact.setPosition(request.getPosition());
        if (StringUtils.hasText(request.getMobile())) contact.setMobile(request.getMobile());
        if (StringUtils.hasText(request.getPhone())) contact.setPhone(request.getPhone());
        if (StringUtils.hasText(request.getEmail())) contact.setEmail(request.getEmail());
        if (StringUtils.hasText(request.getQq())) contact.setQq(request.getQq());
        if (StringUtils.hasText(request.getWechat())) contact.setWechat(request.getWechat());
        if (request.getIsPrimary() != null) contact.setIsPrimary(request.getIsPrimary());
        if (request.getIsEmergency() != null) contact.setIsEmergency(request.getIsEmergency());
        if (StringUtils.hasText(request.getRemark())) contact.setRemark(request.getRemark());

        contactRepository.updateById(contact);

        if (contact.getIsPrimary() != null && contact.getIsPrimary() == 1) {
            clearPrimaryContact(supplierId, contact.getId());
        }

        saveOperationLog(supplierId, operator, "update_contact", "更新联系人: " + contact.getContactName(),
                beforeData, objectMapper.valueToTree(contact).toString());

        return SupplierContactResponse.fromEntity(contact);
    }

    @Override
    @Transactional
    public void deleteContact(Long supplierId, Long contactId, OperatorInfo operator) {
        verifySupplierExists(supplierId);

        SupplierContact contact = contactRepository.selectById(contactId);
        if (contact == null || !contact.getSupplierId().equals(supplierId)) {
            throw new SupplierNotFoundException("联系人不存在: " + contactId);
        }

        contactRepository.deleteById(contactId);
        saveOperationLog(supplierId, operator, "delete_contact", "删除联系人: " + contact.getContactName(),
                objectMapper.valueToTree(contact).toString(), null);
    }

    // ============ 供应商银行账户管理 ============

    @Override
    public List<SupplierBankAccountResponse> listBankAccounts(Long supplierId) {
        verifySupplierExists(supplierId);
        return bankAccountRepository.selectBySupplierId(supplierId).stream()
                .map(SupplierBankAccountResponse::fromEntity)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public SupplierBankAccountResponse createBankAccount(Long supplierId, SupplierBankAccountCreateRequest request, OperatorInfo operator) {
        verifySupplierExists(supplierId);

        SupplierBankAccount account = SupplierBankAccount.builder()
                .supplierId(supplierId)
                .accountName(request.getAccountName())
                .bankName(request.getBankName())
                .bankAccount(request.getBankAccount())
                .branchName(request.getBranchName())
                .branchCode(request.getBranchCode())
                .province(request.getProvince())
                .city(request.getCity())
                .accountType(request.getAccountType())
                .isDefault(request.getIsDefault() != null ? request.getIsDefault() : 0)
                .balance(request.getBalance() != null ? request.getBalance() : BigDecimal.ZERO)
                .reservedPhone(request.getReservedPhone())
                .remark(request.getRemark())
                .build();

        bankAccountRepository.insert(account);

        if (account.getIsDefault() != null && account.getIsDefault() == 1) {
            clearDefaultAccount(supplierId, account.getId());
        }

        saveOperationLog(supplierId, operator, "create_bank_account", "添加银行账户: " + request.getAccountName(),
                null, objectMapper.valueToTree(account).toString());

        return SupplierBankAccountResponse.fromEntity(account);
    }

    @Override
    @Transactional
    public SupplierBankAccountResponse updateBankAccount(Long supplierId, Long accountId, SupplierBankAccountUpdateRequest request, OperatorInfo operator) {
        verifySupplierExists(supplierId);

        SupplierBankAccount account = bankAccountRepository.selectById(accountId);
        if (account == null || !account.getSupplierId().equals(supplierId)) {
            throw new SupplierNotFoundException("银行账户不存在: " + accountId);
        }

        String beforeData = objectMapper.valueToTree(account).toString();

        if (StringUtils.hasText(request.getAccountName())) account.setAccountName(request.getAccountName());
        if (StringUtils.hasText(request.getBankName())) account.setBankName(request.getBankName());
        if (StringUtils.hasText(request.getBankAccount())) account.setBankAccount(request.getBankAccount());
        if (StringUtils.hasText(request.getBranchName())) account.setBranchName(request.getBranchName());
        if (StringUtils.hasText(request.getBranchCode())) account.setBranchCode(request.getBranchCode());
        if (StringUtils.hasText(request.getProvince())) account.setProvince(request.getProvince());
        if (StringUtils.hasText(request.getCity())) account.setCity(request.getCity());
        if (StringUtils.hasText(request.getAccountType())) account.setAccountType(request.getAccountType());
        if (request.getIsDefault() != null) account.setIsDefault(request.getIsDefault());
        if (request.getBalance() != null) account.setBalance(request.getBalance());
        if (StringUtils.hasText(request.getReservedPhone())) account.setReservedPhone(request.getReservedPhone());
        if (StringUtils.hasText(request.getRemark())) account.setRemark(request.getRemark());

        bankAccountRepository.updateById(account);

        if (account.getIsDefault() != null && account.getIsDefault() == 1) {
            clearDefaultAccount(supplierId, account.getId());
        }

        saveOperationLog(supplierId, operator, "update_bank_account", "更新银行账户: " + account.getAccountName(),
                beforeData, objectMapper.valueToTree(account).toString());

        return SupplierBankAccountResponse.fromEntity(account);
    }

    @Override
    @Transactional
    public void deleteBankAccount(Long supplierId, Long accountId, OperatorInfo operator) {
        verifySupplierExists(supplierId);

        SupplierBankAccount account = bankAccountRepository.selectById(accountId);
        if (account == null || !account.getSupplierId().equals(supplierId)) {
            throw new SupplierNotFoundException("银行账户不存在: " + accountId);
        }

        bankAccountRepository.deleteById(accountId);
        saveOperationLog(supplierId, operator, "delete_bank_account", "删除银行账户: " + account.getAccountName(),
                objectMapper.valueToTree(account).toString(), null);
    }

    @Override
    @Transactional
    public void setDefaultBankAccount(Long supplierId, Long accountId, OperatorInfo operator) {
        verifySupplierExists(supplierId);

        SupplierBankAccount account = bankAccountRepository.selectById(accountId);
        if (account == null || !account.getSupplierId().equals(supplierId)) {
            throw new SupplierNotFoundException("银行账户不存在: " + accountId);
        }

        clearDefaultAccount(supplierId, null);
        account.setIsDefault(1);
        bankAccountRepository.updateById(account);

        saveOperationLog(supplierId, operator, "set_default_bank_account", "设置默认银行账户",
                null, objectMapper.valueToTree(account).toString());
    }

    // ============ 供应商评级管理 ============

    @Override
    public PageResponse<SupplierRatingResponse> listRatings(SupplierRatingQueryRequest request) {
        Page<SupplierRating> page = new Page<>(request.getPage(), request.getLimit());
        IPage<SupplierRating> ratingPage = ratingRepository.selectRatingPage(page,
                request.getSupplierId(), request.getGrade(),
                request.getRatingYear(), request.getRatingPeriod());

        List<SupplierRatingResponse> list = ratingPage.getRecords().stream()
                .map(r -> {
                    SupplierRatingResponse resp = SupplierRatingResponse.fromEntity(r);
                    Supplier supplier = supplierRepository.selectById(r.getSupplierId());
                    if (supplier != null) {
                        resp.setSupplierName(supplier.getSupplierName());
                    }
                    return resp;
                })
                .collect(Collectors.toList());

        return PageResponse.of(list, ratingPage.getTotal(),
                (int) ratingPage.getCurrent(), request.getLimit());
    }

    @Override
    public SupplierRatingResponse getSupplierRating(Long id) {
        SupplierRating rating = ratingRepository.selectById(id);
        if (rating == null) {
            throw new SupplierNotFoundException("评级记录不存在: " + id);
        }
        SupplierRatingResponse resp = SupplierRatingResponse.fromEntity(rating);
        Supplier supplier = supplierRepository.selectById(rating.getSupplierId());
        if (supplier != null) {
            resp.setSupplierName(supplier.getSupplierName());
        }
        return resp;
    }

    @Override
    @Transactional
    public SupplierRatingResponse createRating(SupplierRatingCreateRequest request, OperatorInfo operator) {
        verifySupplierExists(request.getSupplierId());

        // 计算综合评分
        BigDecimal quality = request.getQualityScore() != null ? request.getQualityScore() : BigDecimal.ZERO;
        BigDecimal delivery = request.getDeliveryScore() != null ? request.getDeliveryScore() : BigDecimal.ZERO;
        BigDecimal price = request.getPriceScore() != null ? request.getPriceScore() : BigDecimal.ZERO;
        BigDecimal service = request.getServiceScore() != null ? request.getServiceScore() : BigDecimal.ZERO;

        BigDecimal overall = quality.multiply(BigDecimal.valueOf(0.3))
                .add(delivery.multiply(BigDecimal.valueOf(0.25)))
                .add(price.multiply(BigDecimal.valueOf(0.25)))
                .add(service.multiply(BigDecimal.valueOf(0.2)));

        String grade = calculateGrade(overall);

        SupplierRating rating = SupplierRating.builder()
                .supplierId(request.getSupplierId())
                .ratingPeriod(request.getRatingPeriod() != null ? request.getRatingPeriod() : "monthly")
                .ratingYear(request.getRatingYear() != null ? request.getRatingYear() : LocalDateTime.now().getYear())
                .ratingMonth(request.getRatingMonth() != null ? request.getRatingMonth() : LocalDateTime.now().getMonthValue())
                .qualityScore(quality)
                .deliveryScore(delivery)
                .priceScore(price)
                .serviceScore(service)
                .overallScore(overall)
                .grade(grade)
                .evaluatorId(operator.getOperatorId())
                .evaluatorName(operator.getOperatorName())
                .evaluationTime(LocalDateTime.now())
                .strengths(request.getStrengths())
                .weaknesses(request.getWeaknesses())
                .suggestions(request.getSuggestions())
                .remark(request.getRemark())
                .build();

        ratingRepository.insert(rating);

        // 更新供应商当前等级和信用评分
        updateSupplierGrade(request.getSupplierId(), grade, overall.intValue());

        saveOperationLog(request.getSupplierId(), operator, "create_rating", "创建评级: " + grade,
                null, objectMapper.valueToTree(rating).toString());

        SupplierRatingResponse resp = SupplierRatingResponse.fromEntity(rating);
        Supplier supplier = supplierRepository.selectById(request.getSupplierId());
        if (supplier != null) {
            resp.setSupplierName(supplier.getSupplierName());
        }
        return resp;
    }

    @Override
    public SupplierRatingResponse getLatestRatingBySupplierId(Long supplierId) {
        SupplierRating rating = ratingRepository.selectLatestBySupplierId(supplierId);
        if (rating == null) {
            throw new SupplierNotFoundException("该供应商暂无评级记录: " + supplierId);
        }
        SupplierRatingResponse resp = SupplierRatingResponse.fromEntity(rating);
        Supplier supplier = supplierRepository.selectById(supplierId);
        if (supplier != null) {
            resp.setSupplierName(supplier.getSupplierName());
        }
        return resp;
    }

    // ============ 采购询价管理 ============

    @Override
    public PageResponse<ProcurementInquiryResponse> listInquiries(ProcurementInquiryQueryRequest request) {
        Page<ProcurementInquiry> page = new Page<>(request.getPage(), request.getLimit());
        IPage<ProcurementInquiry> inquiryPage = inquiryRepository.selectInquiryPage(page,
                request.getSupplierId(), request.getInquiryStatus(),
                request.getInquiryType(), request.getKeyword(),
                request.getStartDate(), request.getEndDate());

        List<ProcurementInquiryResponse> list = inquiryPage.getRecords().stream()
                .map(ProcurementInquiryResponse::fromEntity)
                .collect(Collectors.toList());

        return PageResponse.of(list, inquiryPage.getTotal(),
                (int) inquiryPage.getCurrent(), request.getLimit());
    }

    @Override
    public ProcurementInquiryResponse getInquiry(Long id) {
        ProcurementInquiry inquiry = inquiryRepository.selectById(id);
        if (inquiry == null) {
            throw new SupplierNotFoundException("询价单不存在: " + id);
        }
        return ProcurementInquiryResponse.fromEntity(inquiry);
    }

    @Override
    @Transactional
    public ProcurementInquiryResponse createInquiry(ProcurementInquiryCreateRequest request, OperatorInfo operator) {
        verifySupplierExists(request.getSupplierId());

        String inquiryNo = generateInquiryNo();

        Supplier supplier = supplierRepository.selectById(request.getSupplierId());

        ProcurementInquiry inquiry = ProcurementInquiry.builder()
                .inquiryNo(inquiryNo)
                .supplierId(request.getSupplierId())
                .supplierName(supplier != null ? supplier.getSupplierName() : "")
                .inquiryType(request.getInquiryType())
                .productId(request.getProductId())
                .productName(request.getProductName())
                .productSpec(request.getProductSpec())
                .unit(request.getUnit())
                .quantity(request.getQuantity())
                .expectedDeliveryDate(request.getExpectedDeliveryDate())
                .inquiryStatus("draft")
                .inquiryDate(LocalDateTime.now())
                .quoteDeadline(request.getQuoteDeadline())
                .quotedPrice(request.getQuotedPrice())
                .currency(request.getCurrency() != null ? request.getCurrency() : "CNY")
                .quoteValidUntil(request.getQuoteValidUntil())
                .deliveryCycle(request.getDeliveryCycle())
                .qualityStandard(request.getQualityStandard())
                .paymentTerms(request.getPaymentTerms())
                .remark(request.getRemark())
                .isSelected(0)
                .creatorId(operator.getOperatorId())
                .creatorName(operator.getOperatorName())
                .build();

        inquiryRepository.insert(inquiry);

        saveOperationLog(request.getSupplierId(), operator, "create_inquiry", "创建询价单: " + inquiryNo,
                null, objectMapper.valueToTree(inquiry).toString());

        return ProcurementInquiryResponse.fromEntity(inquiry);
    }

    @Override
    @Transactional
    public ProcurementInquiryResponse updateInquiry(Long id, ProcurementInquiryUpdateRequest request, OperatorInfo operator) {
        ProcurementInquiry inquiry = inquiryRepository.selectById(id);
        if (inquiry == null) {
            throw new SupplierNotFoundException("询价单不存在: " + id);
        }

        String beforeData = objectMapper.valueToTree(inquiry).toString();

        if (StringUtils.hasText(request.getInquiryType())) inquiry.setInquiryType(request.getInquiryType());
        if (request.getProductId() != null) inquiry.setProductId(request.getProductId());
        if (StringUtils.hasText(request.getProductName())) inquiry.setProductName(request.getProductName());
        if (StringUtils.hasText(request.getProductSpec())) inquiry.setProductSpec(request.getProductSpec());
        if (StringUtils.hasText(request.getUnit())) inquiry.setUnit(request.getUnit());
        if (request.getQuantity() != null) inquiry.setQuantity(request.getQuantity());
        if (StringUtils.hasText(request.getExpectedDeliveryDate())) inquiry.setExpectedDeliveryDate(request.getExpectedDeliveryDate());
        if (StringUtils.hasText(request.getQuoteDeadline())) inquiry.setQuoteDeadline(request.getQuoteDeadline());
        if (request.getQuotedPrice() != null) inquiry.setQuotedPrice(request.getQuotedPrice());
        if (StringUtils.hasText(request.getCurrency())) inquiry.setCurrency(request.getCurrency());
        if (StringUtils.hasText(request.getQuoteValidUntil())) inquiry.setQuoteValidUntil(request.getQuoteValidUntil());
        if (request.getDeliveryCycle() != null) inquiry.setDeliveryCycle(request.getDeliveryCycle());
        if (StringUtils.hasText(request.getQualityStandard())) inquiry.setQualityStandard(request.getQualityStandard());
        if (StringUtils.hasText(request.getPaymentTerms())) inquiry.setPaymentTerms(request.getPaymentTerms());
        if (StringUtils.hasText(request.getRemark())) inquiry.setRemark(request.getRemark());

        inquiryRepository.updateById(inquiry);

        saveOperationLog(inquiry.getSupplierId(), operator, "update_inquiry", "更新询价单: " + inquiry.getInquiryNo(),
                beforeData, objectMapper.valueToTree(inquiry).toString());

        return ProcurementInquiryResponse.fromEntity(inquiry);
    }

    @Override
    @Transactional
    public ProcurementInquiryResponse sendInquiry(Long id, OperatorInfo operator) {
        ProcurementInquiry inquiry = inquiryRepository.selectById(id);
        if (inquiry == null) {
            throw new SupplierNotFoundException("询价单不存在: " + id);
        }

        if (!"draft".equals(inquiry.getInquiryStatus())) {
            throw new SupplierException("只有草稿状态的询价单可以发送");
        }

        String beforeData = objectMapper.valueToTree(inquiry).toString();
        inquiry.setInquiryStatus("sent");
        inquiryRepository.updateById(inquiry);

        saveOperationLog(inquiry.getSupplierId(), operator, "send_inquiry", "发送询价单: " + inquiry.getInquiryNo(),
                beforeData, objectMapper.valueToTree(inquiry).toString());

        return ProcurementInquiryResponse.fromEntity(inquiry);
    }

    @Override
    @Transactional
    public ProcurementInquiryResponse replyInquiry(Long id, BigDecimal quotedPrice, String quoteValidUntil, Integer deliveryCycle, OperatorInfo operator) {
        ProcurementInquiry inquiry = inquiryRepository.selectById(id);
        if (inquiry == null) {
            throw new SupplierNotFoundException("询价单不存在: " + id);
        }

        if (!"sent".equals(inquiry.getInquiryStatus())) {
            throw new SupplierException("只有已发送的询价单可以报价");
        }

        String beforeData = objectMapper.valueToTree(inquiry).toString();
        inquiry.setQuotedPrice(quotedPrice);
        inquiry.setQuoteValidUntil(quoteValidUntil);
        inquiry.setDeliveryCycle(deliveryCycle);
        inquiry.setInquiryStatus("replied");
        inquiryRepository.updateById(inquiry);

        saveOperationLog(inquiry.getSupplierId(), operator, "reply_inquiry", "询价单报价: " + inquiry.getInquiryNo(),
                beforeData, objectMapper.valueToTree(inquiry).toString());

        return ProcurementInquiryResponse.fromEntity(inquiry);
    }

    @Override
    @Transactional
    public ProcurementInquiryResponse confirmInquiry(Long id, String selectionReason, OperatorInfo operator) {
        ProcurementInquiry inquiry = inquiryRepository.selectById(id);
        if (inquiry == null) {
            throw new SupplierNotFoundException("询价单不存在: " + id);
        }

        if (!"replied".equals(inquiry.getInquiryStatus())) {
            throw new SupplierException("只有已报价的询价单可以确认");
        }

        String beforeData = objectMapper.valueToTree(inquiry).toString();
        inquiry.setInquiryStatus("confirmed");
        inquiry.setIsSelected(1);
        inquiry.setSelectionReason(selectionReason);
        inquiryRepository.updateById(inquiry);

        saveOperationLog(inquiry.getSupplierId(), operator, "confirm_inquiry", "确认询价单: " + inquiry.getInquiryNo(),
                beforeData, objectMapper.valueToTree(inquiry).toString());

        return ProcurementInquiryResponse.fromEntity(inquiry);
    }

    @Override
    @Transactional
    public ProcurementInquiryResponse cancelInquiry(Long id, OperatorInfo operator) {
        ProcurementInquiry inquiry = inquiryRepository.selectById(id);
        if (inquiry == null) {
            throw new SupplierNotFoundException("询价单不存在: " + id);
        }

        if ("confirmed".equals(inquiry.getInquiryStatus()) || "cancelled".equals(inquiry.getInquiryStatus())) {
            throw new SupplierException("已确认或已取消的询价单不能取消");
        }

        String beforeData = objectMapper.valueToTree(inquiry).toString();
        inquiry.setInquiryStatus("cancelled");
        inquiryRepository.updateById(inquiry);

        saveOperationLog(inquiry.getSupplierId(), operator, "cancel_inquiry", "取消询价单: " + inquiry.getInquiryNo(),
                beforeData, objectMapper.valueToTree(inquiry).toString());

        return ProcurementInquiryResponse.fromEntity(inquiry);
    }

    // ============ 统计分析 ============

    @Override
    public SupplierStatisticsResponse getStatistics() {
        Long totalSuppliers = supplierRepository.selectCount(null);
        Long activeSuppliers = supplierRepository.countActiveSuppliers();
        Long pendingSuppliers = supplierRepository.selectCount(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Supplier>()
                        .eq(Supplier::getStatus, "pending"));

        Map<String, Long> gradeDistribution = new LinkedHashMap<>();
        List<SupplierRepository.GradeCount> gradeCounts = supplierRepository.countByGrade();
        for (SupplierRepository.GradeCount gc : gradeCounts) {
            gradeDistribution.put(gc.getGrade(), gc.getCount());
        }

        Map<String, Long> typeDistribution = new LinkedHashMap<>();
        List<SupplierRepository.TypeCount> typeCounts = supplierRepository.countByType();
        for (SupplierRepository.TypeCount tc : typeCounts) {
            typeDistribution.put(tc.getSupplierType(), tc.getCount());
        }

        // 获取A级供应商列表
        List<Supplier> topGradeSuppliers = supplierRepository.selectList(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Supplier>()
                        .eq(Supplier::getGrade, "A")
                        .orderByDesc(Supplier::getCreditScore)
                        .last("LIMIT 10"));

        List<SupplierStatisticsResponse.TopSupplierResponse> topGradeList = topGradeSuppliers.stream()
                .map(s -> SupplierStatisticsResponse.TopSupplierResponse.builder()
                        .id(s.getId())
                        .supplierCode(s.getSupplierCode())
                        .supplierName(s.getSupplierName())
                        .grade(s.getGrade())
                        .creditScore(s.getCreditScore())
                        .status(s.getStatus())
                        .build())
                .collect(Collectors.toList());

        // 获取最近合作的供应商
        List<Supplier> recentSuppliers = supplierRepository.selectList(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Supplier>()
                        .orderByDesc(Supplier::getCreatedAt)
                        .last("LIMIT 10"));

        List<SupplierStatisticsResponse.TopSupplierResponse> recentList = recentSuppliers.stream()
                .map(s -> SupplierStatisticsResponse.TopSupplierResponse.builder()
                        .id(s.getId())
                        .supplierCode(s.getSupplierCode())
                        .supplierName(s.getSupplierName())
                        .grade(s.getGrade())
                        .creditScore(s.getCreditScore())
                        .status(s.getStatus())
                        .build())
                .collect(Collectors.toList());

        return SupplierStatisticsResponse.builder()
                .totalSuppliers(totalSuppliers)
                .activeSuppliers(activeSuppliers)
                .pendingSuppliers(pendingSuppliers)
                .gradeDistribution(gradeDistribution)
                .typeDistribution(typeDistribution)
                .topGradeSuppliers(topGradeList)
                .recentCooperationSuppliers(recentList)
                .build();
    }

    // ============ 辅助方法 ============

    private SupplierResponse enrichSupplierResponse(SupplierResponse response, Long supplierId) {
        // 加载联系人
        List<SupplierContact> contacts = contactRepository.selectBySupplierId(supplierId);
        if (contacts != null && !contacts.isEmpty()) {
            response.setContacts(contacts.stream()
                    .map(SupplierContactResponse::fromEntity)
                    .collect(Collectors.toList()));
        }

        // 加载银行账户
        List<SupplierBankAccount> accounts = bankAccountRepository.selectBySupplierId(supplierId);
        if (accounts != null && !accounts.isEmpty()) {
            response.setBankAccounts(accounts.stream()
                    .map(SupplierBankAccountResponse::fromEntity)
                    .collect(Collectors.toList()));
        }

        return response;
    }

    private void verifySupplierExists(Long supplierId) {
        if (supplierRepository.selectById(supplierId) == null) {
            throw new SupplierNotFoundException("供应商不存在: " + supplierId);
        }
    }

    private String generateSupplierCode() {
        return codePrefix + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))
                + UUID.randomUUID().toString().substring(0, 6).toUpperCase();
    }

    private String generateInquiryNo() {
        return "INQ" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))
                + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }

    private String calculateGrade(BigDecimal score) {
        if (score == null) return "D";
        int s = score.intValue();
        if (s >= 90) return "A";
        if (s >= 75) return "B";
        if (s >= 60) return "C";
        return "D";
    }

    private void updateSupplierGrade(Long supplierId, String grade, Integer creditScore) {
        Supplier supplier = supplierRepository.selectById(supplierId);
        if (supplier != null) {
            supplier.setGrade(grade);
            supplier.setCreditScore(creditScore);
            supplierRepository.updateById(supplier);
        }
    }

    private void clearPrimaryContact(Long supplierId, Long exceptContactId) {
        List<SupplierContact> contacts = contactRepository.selectBySupplierId(supplierId);
        for (SupplierContact c : contacts) {
            if (!c.getId().equals(exceptContactId) && c.getIsPrimary() != null && c.getIsPrimary() == 1) {
                c.setIsPrimary(0);
                contactRepository.updateById(c);
            }
        }
    }

    private void clearDefaultAccount(Long supplierId, Long exceptAccountId) {
        List<SupplierBankAccount> accounts = bankAccountRepository.selectBySupplierId(supplierId);
        for (SupplierBankAccount a : accounts) {
            if (!a.getId().equals(exceptAccountId) && a.getIsDefault() != null && a.getIsDefault() == 1) {
                a.setIsDefault(0);
                bankAccountRepository.updateById(a);
            }
        }
    }

    private void saveOperationLog(Long supplierId, OperatorInfo operator, String operationType, String operationDesc,
                                   String beforeData, String afterData) {
        SupplierOperationLog log = SupplierOperationLog.builder()
                .supplierId(supplierId)
                .operatorId(operator.getOperatorId())
                .operatorName(operator.getOperatorName())
                .operationType(operationType)
                .operationDesc(operationDesc)
                .beforeData(beforeData)
                .afterData(afterData)
                .ip(operator.getIp())
                .userAgent(operator.getUserAgent())
                .build();
        operationLogRepository.insert(log);
    }
}
