package com.huimv.employment.controller.mp;

import com.huimv.employment.common.exception.BizException;
import com.huimv.employment.common.exception.ErrorCode;
import com.huimv.employment.common.web.R;
import com.huimv.employment.security.LoginUser;
import com.huimv.employment.security.LoginUserHolder;
import com.huimv.employment.service.order.TaskPublishService;
import com.huimv.employment.service.order.dto.OrderCompleteRequest;
import com.huimv.employment.service.order.dto.OrderCompleteResponse;
import com.huimv.employment.service.order.dto.TaskPublishDetailResponse;
import com.huimv.employment.service.order.dto.TaskPublishRequest;
import com.huimv.employment.service.order.dto.TaskPublishResponse;
import com.huimv.employment.service.settlement.OrderInvoiceService;
import com.huimv.employment.service.settlement.SettlementService;
import com.huimv.employment.service.settlement.dto.OrderInvoiceResponse;
import com.huimv.employment.service.settlement.dto.SettlementConfirmPayRequest;
import com.huimv.employment.service.settlement.dto.SettlementSummaryResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 企业端用工订单接口（小程序 JWT）。
 */
@RestController
@RequestMapping("/api/v1/mp/orders")
@Tag(name = "用工订单", description = "任务发布、结算确认支付、开票归档、结算查询等；需企业 JWT 鉴权")
@SecurityRequirement(name = "Authorization")
public class EmploymentOrderController {

    private static final String USER_TYPE_ENTERPRISE = "enterprise";

    private final SettlementService settlementService;
    private final TaskPublishService taskPublishService;
    private final OrderInvoiceService orderInvoiceService;

    public EmploymentOrderController(SettlementService settlementService,
                                     TaskPublishService taskPublishService,
                                     OrderInvoiceService orderInvoiceService) {
        this.settlementService = settlementService;
        this.taskPublishService = taskPublishService;
        this.orderInvoiceService = orderInvoiceService;
    }

    @GetMapping("/{orderId}/publish-task")
    @Operation(summary = "查询任务发布详情",
            description = "按订单 ID 返回任务发布页数据：订单编号/标题/步骤、计划与已登记人数、"
                    + "各工种岗位类型/用工人数/工作地点/工作天数及计划起止日（work_start_date / work_end_date）。"
                    + "仅可查询本企业订单。")
    public R<TaskPublishDetailResponse> getPublishTaskDetail(@PathVariable("orderId") Long orderId) {
        LoginUser loginUser = requireEnterprise();
        return R.ok(taskPublishService.getDetail(loginUser.getUserId(), orderId));
    }

    @PostMapping("/{orderId}/publish-task")
    @Operation(summary = "任务发布",
            description = "按订单 ID：1）校验本单人员登记已完成（reg_status=completed 人数 ≥ 计划人数）；"
                    + "2）更新 fe_order_work_item 各工种 work_start_date / work_end_date；"
                    + "3）工作流推进到 task_publish；"
                    + "4）生成 fe_settlement_order（进入 settlement_pending）。"
                    + "work_items 按 id / group_no / job_type 匹配；须覆盖全部缺少起止日的工种。"
                    + "人员登记未完成（未招满）时须传 allow_understaffed=true，且至少 1 人已完成登记。"
                    + "幂等：已有结算单则直接返回。")
    public R<TaskPublishResponse> publishTask(@PathVariable("orderId") Long orderId,
                                              @Validated @RequestBody TaskPublishRequest request) {
        LoginUser loginUser = requireEnterprise();
        return R.ok(taskPublishService.publish(loginUser.getUserId(), orderId, request));
    }

    @GetMapping("/{orderId}/settlement")
    @Operation(summary = "查询订单结算信息",
            description = "返回该订单当前有效结算单（非 cancelled）摘要，含明细与费用分项。"
                    + "尚未生成结算单时返回 404。仅可查询本企业订单。")
    public R<SettlementSummaryResponse> getSettlement(@PathVariable("orderId") Long orderId) {
        LoginUser loginUser = requireEnterprise();
        return R.ok(settlementService.getActiveSettlement(loginUser.getUserId(), orderId));
    }

    @PostMapping("/{orderId}/confirm-pay-settlement")
    @Operation(summary = "确认结算并支付",
            description = "须任务发布已完成（步骤 ≥ task_publish，且工种起止日已写入），"
                    + "且订单处于 settlement_pending 时可调用。"
                    + "结算单置为 paid，写入 Mock 支付记录；"
                    + "订单推进到 invoice_archive（结算打款节点 done，当前节点为开票归档）。"
                    + "可选 payment_channel：wechat / alipay / bank，默认 wechat。幂等。")
    public R<SettlementSummaryResponse> confirmPaySettlement(
            @PathVariable("orderId") Long orderId,
            @RequestBody(required = false) SettlementConfirmPayRequest request) {
        LoginUser loginUser = requireEnterprise();
        return R.ok(settlementService.confirmAndPay(loginUser.getUserId(), orderId, request));
    }

    @GetMapping("/{orderId}/invoice")
    @Operation(summary = "查询订单开票信息",
            description = "返回开票归档页数据：可开票/已开票/待开票金额、发票类型与税率、税额与价税合计、"
                    + "开票抬头（企业名称/信用代码/开户行账号）及可下载文件。"
                    + "未归档时按结算单与企业资料预填；已归档返回 fe_order_invoice 落库数据。")
    public R<OrderInvoiceResponse> getInvoice(@PathVariable("orderId") Long orderId) {
        LoginUser loginUser = requireEnterprise();
        return R.ok(orderInvoiceService.getInvoice(loginUser.getUserId(), orderId));
    }

    @PostMapping("/{orderId}/invoice-archive")
    @Operation(summary = "开票归档（保存开票信息并办结）",
            description = "须本单已确认结算并支付（结算单 status=paid，且有确认时间或成功支付记录），"
                    + "且订单处于 invoice_archive（或历史 settlement_paid）时可调用。"
                    + "写入 fe_order_invoice（开票金额、税额、抬头等），"
                    + "订单 current_step_code → completed、order_status → completed，流程结束。幂等。"
                    + "可传：company_name、credit_code、bank_account_info、invoice_type、tax_rate、"
                    + "invoice_amount、tax_amount、total_with_tax、invoice_no、tax_voucher_no、remark；"
                    + "tax_cleared / invoice_issued 默认 true。")
    public R<OrderCompleteResponse> invoiceArchive(
            @PathVariable("orderId") Long orderId,
            @RequestBody(required = false) OrderCompleteRequest request) {
        LoginUser loginUser = requireEnterprise();
        return R.ok(settlementService.completeOrder(loginUser.getUserId(), orderId, request));
    }

    private static LoginUser requireEnterprise() {
        LoginUser loginUser = LoginUserHolder.require();
        if (!USER_TYPE_ENTERPRISE.equals(loginUser.getUserType())) {
            throw new BizException(ErrorCode.ENTERPRISE_ONLY);
        }
        return loginUser;
    }
}
