package com.zt.plat.module.base.controller.admin.doctemplate.render;

import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.base.controller.admin.doctemplate.render.vo.*;
import com.zt.plat.module.base.service.doctemplate.render.DocTemplateAdvancedRenderService;
import com.zt.plat.module.base.service.doctemplate.render.DocTemplateDataSourceType;
import com.zt.plat.module.base.service.doctemplate.render.TemplateRenderRequest;
import com.zt.plat.module.base.service.doctemplate.render.export.ExportType;
import com.zt.plat.module.base.service.doctemplate.render.export.WordExportResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.module.base.enums.ErrorCodeConstants.*;

/**
 * 文档模板渲染控制器
 */
@RestController
@RequestMapping("/base/doc-template-instance")
@Tag(name = "管理后台 - 文档模板渲染")
@Slf4j
public class DocTemplateRenderController {

    @Resource
    private DocTemplateAdvancedRenderService advancedRenderService;

    @PostMapping("/preview/default")
    @Operation(summary = "默认值预览")
    @PreAuthorize("@ss.hasPermission('base:doctemplate:render')")
    public CommonResult<String> previewWithDefaultValues(
            @RequestParam("templateInstanceId") Long templateInstanceId) {
        log.info("默认值预览: {}", templateInstanceId);
        try {
            TemplateRenderRequest request = new TemplateRenderRequest();
            request.setTemplateInstanceId(templateInstanceId);
            request.setExportType(ExportType.HTML_PREVIEW);
            Object result = advancedRenderService.renderAndExport(request);
            return CommonResult.success(result.toString());
        } catch (Exception e) {
            log.error("预览失败", e);
            return CommonResult.error(500, "预览失败: " + e.getMessage());
        }
    }

    @PostMapping("/preview/business")
    @Operation(summary = "业务数据预览")
    @PreAuthorize("@ss.hasPermission('base:doctemplate:render')")
    public CommonResult<String> previewWithBusinessData(@RequestBody BusinessPreviewRequest request) {
        log.info("业务预览: {}", request.getTemplateInstanceId());
        try {
            Map<String, DocTemplateDataSourceType> fieldDataSources = new HashMap<>();
            if (request.getFieldMappings() != null) {
                for (String key : request.getFieldMappings().keySet()) {
                    fieldDataSources.put(key, DocTemplateDataSourceType.BUSINESS);
                }
            }

            TemplateRenderRequest renderRequest = new TemplateRenderRequest();
            renderRequest.setTemplateInstanceId(request.getTemplateInstanceId());
            renderRequest.setBusinessType(request.getBusinessType());
            renderRequest.setDataSourceContext(request.getBusinessId());
            renderRequest.setFieldDataSources(fieldDataSources);
            renderRequest.setExportType(ExportType.HTML_PREVIEW);

            Object result = advancedRenderService.renderAndExport(renderRequest);
            return CommonResult.success(result.toString());
        } catch (Exception e) {
            log.error("业务预览失败", e);
            return CommonResult.error(500, "预览失败: " + e.getMessage());
        }
    }

    @PostMapping("/preview/custom")
    @Operation(summary = "自定义数据预览")
    @PreAuthorize("@ss.hasPermission('base:doctemplate:render')")
    public CommonResult<String> previewWithCustomData(@RequestBody CustomPreviewRequest request) {
        log.info("自定义预览: {}", request.getTemplateInstanceId());
        try {
            Map<String, DocTemplateDataSourceType> fieldDataSources = new HashMap<>();
            if (request.getCustomData() != null) {
                for (String key : request.getCustomData().keySet()) {
                    fieldDataSources.put(key, DocTemplateDataSourceType.REQUEST);
                }
            }

            TemplateRenderRequest renderRequest = new TemplateRenderRequest();
            renderRequest.setTemplateInstanceId(request.getTemplateInstanceId());
            renderRequest.setFieldDataSources(fieldDataSources);
            renderRequest.setDataSourceContext(request.getCustomData());
            renderRequest.setExportType(ExportType.HTML_PREVIEW);

            Object result = advancedRenderService.renderAndExport(renderRequest);
            return CommonResult.success(result.toString());
        } catch (Exception e) {
            log.error("自定义预览失败", e);
            return CommonResult.error(500, "预览失败: " + e.getMessage());
        }
    }

    @PostMapping("/export/default")
    @Operation(summary = "默认值导出Word")
    @PreAuthorize("@ss.hasPermission('base:doctemplate:render')")
    public ResponseEntity<byte[]> exportWithDefaultValues(
            @RequestParam("templateInstanceId") Long templateInstanceId) {
        log.info("默认值导出: {}", templateInstanceId);
        try {
            TemplateRenderRequest request = new TemplateRenderRequest();
            request.setTemplateInstanceId(templateInstanceId);
            request.setExportType(ExportType.WORD);

            Object result = advancedRenderService.renderAndExport(request);

            if (result instanceof WordExportResult) {
                WordExportResult wordResult = (WordExportResult) result;
                String encodedFileName = URLEncoder.encode(wordResult.getFileName(), StandardCharsets.UTF_8).replace("+", "%20");

                return ResponseEntity.ok()
                        .header("Content-Disposition", "attachment; filename=\"document.docx\"; filename*=UTF-8''" + encodedFileName)
                        .header("Content-Type", wordResult.getContentType())
                        .body(wordResult.getFileContent());
            }

            throw exception(TEMPLATE_EXPORT_TYPE_ERROR);
        } catch (Exception e) {
            log.error("默认值导出失败", e);
            throw exception(TEMPLATE_EXPORT_FAILED);
        }
    }

    @PostMapping("/export/business")
    @Operation(summary = "业务数据导出Word")
    @PreAuthorize("@ss.hasPermission('base:doctemplate:render')")
    public ResponseEntity<byte[]> exportWithBusinessData(@RequestBody BusinessExportRequest request) {
        log.info("业务导出: {}", request.getTemplateInstanceId());
        try {
            Map<String, DocTemplateDataSourceType> fieldDataSources = new HashMap<>();
            if (request.getFieldMappings() != null) {
                for (String key : request.getFieldMappings().keySet()) {
                    fieldDataSources.put(key, DocTemplateDataSourceType.BUSINESS);
                }
            }

            TemplateRenderRequest renderRequest = new TemplateRenderRequest();
            renderRequest.setTemplateInstanceId(request.getTemplateInstanceId());
            renderRequest.setBusinessType(request.getBusinessType());
            renderRequest.setDataSourceContext(request.getBusinessId());
            renderRequest.setFieldDataSources(fieldDataSources);
            renderRequest.setExportType(ExportType.WORD);

            Object result = advancedRenderService.renderAndExport(renderRequest);

            if (result instanceof WordExportResult) {
                WordExportResult wordResult = (WordExportResult) result;
                String encodedFileName = URLEncoder.encode(wordResult.getFileName(), StandardCharsets.UTF_8).replace("+", "%20");

                return ResponseEntity.ok()
                        .header("Content-Disposition", "attachment; filename=\"document.docx\"; filename*=UTF-8''" + encodedFileName)
                        .header("Content-Type", wordResult.getContentType())
                        .body(wordResult.getFileContent());
            }

            throw exception(TEMPLATE_EXPORT_TYPE_ERROR);
        } catch (Exception e) {
            log.error("业务数据导出失败", e);
            throw exception(TEMPLATE_EXPORT_FAILED);
        }
    }

    @PostMapping("/export/custom")
    @Operation(summary = "自定义数据导出Word")
    @PreAuthorize("@ss.hasPermission('base:doctemplate:render')")
    public void exportWithCustomData(
            @RequestBody CustomExportRequest request,
            jakarta.servlet.http.HttpServletResponse response) throws Exception {
        log.info("自定义导出: {}", request.getTemplateInstanceId());
        try {
            Map<String, DocTemplateDataSourceType> fieldDataSources = new HashMap<>();
            if (request.getCustomData() != null) {
                for (String key : request.getCustomData().keySet()) {
                    fieldDataSources.put(key, DocTemplateDataSourceType.REQUEST);
                }
            }

            TemplateRenderRequest renderRequest = new TemplateRenderRequest();
            renderRequest.setTemplateInstanceId(request.getTemplateInstanceId());
            renderRequest.setFieldDataSources(fieldDataSources);
            renderRequest.setDataSourceContext(request.getCustomData());
            renderRequest.setExportType(ExportType.WORD);

            Object result = advancedRenderService.renderAndExport(renderRequest);

            if (result instanceof WordExportResult) {
                WordExportResult wordResult = (WordExportResult) result;

                // 先设置响应头
                response.addHeader("Content-Disposition", "attachment;filename=" +
                    com.zt.plat.framework.common.util.http.HttpUtils.encodeUtf8(wordResult.getFileName()));
                response.setContentType(wordResult.getContentType());

                // 再写入数据到输出流
                response.getOutputStream().write(wordResult.getFileContent());
                response.getOutputStream().flush();
                return;
            }

            throw exception(TEMPLATE_EXPORT_TYPE_ERROR);
        } catch (Exception e) {
            log.error("自定义数据导出失败", e);
            throw exception(TEMPLATE_EXPORT_FAILED);
        }
    }
}
