package com.corewing.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.corewing.app.common.Result;
import com.corewing.app.dto.qc.StepResultData;
import com.corewing.app.dto.qc.UploadTestRecordRequest;
import com.corewing.app.dto.qc.ValidateSnRequest;
import com.corewing.app.entity.FlightController;
import com.corewing.app.entity.QcPhoto;
import com.corewing.app.entity.QcStepResult;
import com.corewing.app.entity.QcTestRecord;
import com.corewing.app.mapper.FlightControllerMapper;
import com.corewing.app.mapper.QcPhotoMapper;
import com.corewing.app.mapper.QcStepResultMapper;
import com.corewing.app.mapper.QcTestRecordMapper;
import com.corewing.app.service.QcTestService;
import com.corewing.app.util.OSSUploadUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class QcTestServiceImpl extends ServiceImpl<QcTestRecordMapper, QcTestRecord> implements QcTestService {

    @Resource
    private QcStepResultMapper qcStepResultMapper;

    @Resource
    private QcPhotoMapper qcPhotoMapper;

    @Resource
    private FlightControllerMapper flightControllerMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> uploadTestRecord(UploadTestRecordRequest request) {
        if (request.getTestNo() == null || request.getTestNo().isEmpty()) {
            return Result.error("测试单号不能为空");
        }

        // 查找是否已存在相同 testNo 的记录
        LambdaQueryWrapper<QcTestRecord> testNoQuery = new LambdaQueryWrapper<>();
        testNoQuery.eq(QcTestRecord::getTestNo, request.getTestNo());
        QcTestRecord existByTestNo = baseMapper.selectOne(testNoQuery);

        QcTestRecord record;
        if (existByTestNo != null) {
            // 相同 testNo 已存在 → 更新（APP 重传场景）
            record = existByTestNo;
            fillRecord(record, request);
            baseMapper.updateById(record);
            // 清除旧的步骤和照片，后面重新插入
            deleteStepsAndPhotos(record.getId());
        } else {
            // 查找同一 SN 是否已有记录（返修重测场景）
            LambdaQueryWrapper<QcTestRecord> snQuery = new LambdaQueryWrapper<>();
            snQuery.eq(QcTestRecord::getSn, request.getSn())
                    .eq(QcTestRecord::getProductType, request.getProductType())
                    .orderByDesc(QcTestRecord::getCreateTime)
                    .last("LIMIT 1");
            QcTestRecord existBySn = baseMapper.selectOne(snQuery);

            if (existBySn != null) {
                // 同一 SN 已有记录 → 更新最近一条（返修后重新 QC）
                record = existBySn;
                fillRecord(record, request);
                baseMapper.updateById(record);
                deleteStepsAndPhotos(record.getId());
            } else {
                // 全新记录
                record = new QcTestRecord();
                fillRecord(record, request);
                baseMapper.insert(record);
            }
        }

        // 保存步骤结果
        if (!CollectionUtils.isEmpty(request.getSteps())) {
            for (StepResultData stepData : request.getSteps()) {
                QcStepResult step = new QcStepResult();
                BeanUtils.copyProperties(stepData, step, "completedAt");
                step.setTestRecordId(record.getId());
                step.setCompletedAt(parseTimestamp(stepData.getCompletedAt()));
                qcStepResultMapper.insert(step);
            }
        }

        // 保存照片 URL
        if (!CollectionUtils.isEmpty(request.getPhotoUrls())) {
            for (String photoUrl : request.getPhotoUrls()) {
                QcPhoto photo = new QcPhoto();
                photo.setTestRecordId(record.getId());
                photo.setTestNo(request.getTestNo());
                photo.setUrl(photoUrl);
                qcPhotoMapper.insert(photo);
            }
        }

        // 返回报告 URL（可为 null）
        return Result.success("上传成功", record.getReportUrl());
    }

    private void fillRecord(QcTestRecord record, UploadTestRecordRequest request) {
        // 拷贝同名同类型字段（testNo, productType, sn, operatorId, operatorName, phoneModel, appVersion, status）
        BeanUtils.copyProperties(request, record, "createTime", "updatedAt", "uploadTime");
        // 时间戳字符串 → LocalDateTime 需要手动转换
        record.setCreateTime(parseTimestamp(request.getCreateTime()));
        record.setUpdatedAt(parseTimestamp(request.getUpdatedAt()));
        record.setUploadTime(parseTimestamp(request.getUploadTime()));
    }

    private void deleteStepsAndPhotos(Long recordId) {
        LambdaQueryWrapper<QcStepResult> stepDelete = new LambdaQueryWrapper<>();
        stepDelete.eq(QcStepResult::getTestRecordId, recordId);
        qcStepResultMapper.delete(stepDelete);

        LambdaQueryWrapper<QcPhoto> photoDelete = new LambdaQueryWrapper<>();
        photoDelete.eq(QcPhoto::getTestRecordId, recordId);
        qcPhotoMapper.delete(photoDelete);
    }

    @Override
    public Result<Map<String, String>> uploadPhoto(String testNo, MultipartFile photo) {
        if (photo == null || photo.isEmpty()) {
            return Result.error("照片文件不能为空");
        }
        if (testNo == null || testNo.isEmpty()) {
            return Result.error("测试单号不能为空");
        }

        // 查找对应的测试记录
        LambdaQueryWrapper<QcTestRecord> query = new LambdaQueryWrapper<>();
        query.eq(QcTestRecord::getTestNo, testNo);
        QcTestRecord record = baseMapper.selectOne(query);
        if (record == null) {
            return Result.error("测试记录不存在: " + testNo);
        }

        try {
            // 生成 OSS 存储路径
            String originalFilename = photo.getOriginalFilename();
            String suffix = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String objectName = "qc/photos/" + testNo + "/" + UUID.randomUUID().toString().replace("-", "") + suffix;

            // 上传到 OSS
            String url = OSSUploadUtil.uploadFile(photo.getInputStream(), objectName);

            // 保存照片记录
            QcPhoto qcPhoto = new QcPhoto();
            qcPhoto.setTestRecordId(record.getId());
            qcPhoto.setTestNo(testNo);
            qcPhoto.setUrl(url);
            qcPhotoMapper.insert(qcPhoto);

            Map<String, String> result = new HashMap<>();
            result.put("url", url);
            return Result.success("上传成功", result);
        } catch (Exception e) {
            log.error("照片上传失败", e);
            return Result.error("照片上传失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Boolean> validateSn(ValidateSnRequest request) {
        if (request.getSn() == null || request.getSn().isEmpty()) {
            return Result.error("SN 不能为空");
        }

        LambdaQueryWrapper<FlightController> query = new LambdaQueryWrapper<>();
        query.eq(FlightController::getSn, request.getSn());
        Long count = flightControllerMapper.selectCount(query);

        if (count > 0) {
            return Result.success("SN 有效", true);
        }

        return Result.error("SN 无效或未注册");
    }

    @Override
    public Result<List<QcTestRecord>> getHistory(String sn) {
        if (sn == null || sn.isEmpty()) {
            return Result.error("SN 不能为空");
        }

        LambdaQueryWrapper<QcTestRecord> query = new LambdaQueryWrapper<>();
        query.eq(QcTestRecord::getSn, sn)
                .orderByDesc(QcTestRecord::getCreateTime);
        List<QcTestRecord> records = baseMapper.selectList(query);

        return Result.success(records);
    }

    @Override
    public Result<String> getReport(String testNo) {
        if (testNo == null || testNo.isEmpty()) {
            return Result.error("测试单号不能为空");
        }

        LambdaQueryWrapper<QcTestRecord> query = new LambdaQueryWrapper<>();
        query.eq(QcTestRecord::getTestNo, testNo);
        QcTestRecord record = baseMapper.selectOne(query);

        if (record == null) {
            return Result.error("测试记录不存在");
        }

        return Result.success(record.getReportUrl());
    }

    private LocalDateTime parseTimestamp(String timestamp) {
        if (timestamp == null || timestamp.isEmpty()) {
            return null;
        }
        try {
            long millis = Long.parseLong(timestamp);
            if (millis <= 0) {
                return null;
            }
            return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneId.systemDefault());
        } catch (NumberFormatException e) {
            return null;
        }
    }
}
