package com.erp.controller;

import com.erp.dto.ApiResponse;
import com.erp.service.ApprovalService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/approval")
@RequiredArgsConstructor
@Slf4j
public class ApprovalController {

    private final ApprovalService approvalService;

    // ═══════════════════════════════════════════════════════════════
    // approval_definitions
    // ═══════════════════════════════════════════════════════════════

    @GetMapping("/definitions")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDefinitions(
            @RequestParam Map<String, Object> params,
            @RequestAttribute("company_code") String companyCode) {
        params.put("company_code", companyCode);
        return ResponseEntity.ok(ApiResponse.success(approvalService.getDefinitions(params)));
    }

    @GetMapping("/definitions/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getDefinition(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("definition_id", id);
            params.put("company_code",  companyCode);
            return ResponseEntity.ok(ApiResponse.success(approvalService.getDefinition(params)));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
        }
    }

    @PostMapping("/definitions")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createDefinition(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        if (body.get("definition_name") == null)
            return ResponseEntity.status(400).body(ApiResponse.error("결재 유형명은 필수입니다."));
        body.put("company_code", companyCode);
        body.put("user_id", userId);
        try {
            return ResponseEntity.status(HttpStatus.CREATED)
                    .body(ApiResponse.success(approvalService.createDefinition(body), "결재 유형이 생성되었습니다."));
        } catch (Exception e) {
            log.error("결재 유형 생성 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("결재 유형 생성 중 오류가 발생했습니다."));
        }
    }

    @PutMapping("/definitions/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateDefinition(
            @PathVariable Long id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("definition_id", id);
        body.put("company_code",  companyCode);
        body.put("user_id",       userId);
        try {
            return ResponseEntity.ok(ApiResponse.success(approvalService.updateDefinition(body), "결재 유형이 수정되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("결재 유형 수정 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("결재 유형 수정 중 오류가 발생했습니다."));
        }
    }

    @DeleteMapping("/definitions/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteDefinition(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("definition_id", id);
        params.put("company_code",  companyCode);
        try {
            approvalService.deleteDefinition(params);
            return ResponseEntity.ok(ApiResponse.success(null, "결재 유형이 삭제되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("결재 유형 삭제 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("결재 유형 삭제 중 오류가 발생했습니다."));
        }
    }

    // ═══════════════════════════════════════════════════════════════
    // approval_line_templates
    // ═══════════════════════════════════════════════════════════════

    @GetMapping("/templates")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getTemplates(
            @RequestParam Map<String, Object> params,
            @RequestAttribute("company_code") String companyCode) {
        params.put("company_code", companyCode);
        return ResponseEntity.ok(ApiResponse.success(approvalService.getTemplates(params)));
    }

    @GetMapping("/templates/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getTemplate(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("template_id",  id);
            params.put("company_code", companyCode);
            return ResponseEntity.ok(ApiResponse.success(approvalService.getTemplate(params)));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
        }
    }

    @PostMapping("/templates")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createTemplate(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        if (body.get("template_name") == null)
            return ResponseEntity.status(400).body(ApiResponse.error("템플릿명은 필수입니다."));
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            return ResponseEntity.status(HttpStatus.CREATED)
                    .body(ApiResponse.success(approvalService.createTemplate(body), "결재선 템플릿이 생성되었습니다."));
        } catch (Exception e) {
            log.error("템플릿 생성 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("결재선 템플릿 생성 중 오류가 발생했습니다."));
        }
    }

    @PutMapping("/templates/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateTemplate(
            @PathVariable Long id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("template_id",  id);
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            return ResponseEntity.ok(ApiResponse.success(approvalService.updateTemplate(body), "결재선 템플릿이 수정되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("템플릿 수정 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("결재선 템플릿 수정 중 오류가 발생했습니다."));
        }
    }

    @DeleteMapping("/templates/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteTemplate(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("template_id",  id);
        params.put("company_code", companyCode);
        try {
            approvalService.deleteTemplate(params);
            return ResponseEntity.ok(ApiResponse.success(null, "결재선 템플릿이 삭제되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("템플릿 삭제 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("결재선 템플릿 삭제 중 오류가 발생했습니다."));
        }
    }

    // ═══════════════════════════════════════════════════════════════
    // approval_requests
    // ═══════════════════════════════════════════════════════════════

    @GetMapping("/requests")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getRequests(
            @RequestParam Map<String, Object> params,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @RequestAttribute(name = "effective_user_ids", required = false) List<String> effectiveUserIds) {
        params.put("company_code", companyCode);
        params.put("user_id",      userId);
        params.put("effective_user_ids", effectiveUserIds);
        return ResponseEntity.ok(ApiResponse.success(approvalService.getRequests(params)));
    }

    @GetMapping("/requests/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getRequest(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("request_id",  id);
            params.put("company_code", companyCode);
            return ResponseEntity.ok(ApiResponse.success(approvalService.getRequest(params)));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
        }
    }

    @PostMapping("/requests")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createRequest(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            return ResponseEntity.status(HttpStatus.CREATED)
                    .body(ApiResponse.success(approvalService.createRequest(body), "결재 요청이 생성되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("결재 요청 생성 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("결재 요청 생성 중 오류가 발생했습니다."));
        }
    }

    @PostMapping("/requests/{id}/cancel")
    public ResponseEntity<ApiResponse<Void>> cancelRequest(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("request_id",  id);
        params.put("company_code", companyCode);
        params.put("user_id",     userId);
        try {
            approvalService.cancelRequest(params);
            return ResponseEntity.ok(ApiResponse.success(null, "결재 요청이 회수되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("결재 요청 회수 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("결재 요청 회수 중 오류가 발생했습니다."));
        }
    }

    @PostMapping("/requests/{id}/post-approve")
    public ResponseEntity<ApiResponse<Void>> postApprove(
            @PathVariable Long id,
            @RequestBody(required = false) Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        Map<String, Object> params = new HashMap<>();
        if (body != null) params.putAll(body);
        params.put("request_id",  id);
        params.put("company_code", companyCode);
        params.put("user_id",     userId);
        try {
            approvalService.postApprove(params);
            return ResponseEntity.ok(ApiResponse.success(null, "후결 처리가 완료되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("후결 처리 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("후결 처리 중 오류가 발생했습니다."));
        }
    }

    // ═══════════════════════════════════════════════════════════════
    // approval_lines
    // ═══════════════════════════════════════════════════════════════

    @GetMapping("/my-pending")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getMyPendingLines(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @RequestAttribute(name = "effective_user_ids", required = false) List<String> effectiveUserIds) {
        Map<String, Object> params = new HashMap<>();
        params.put("company_code", companyCode);
        params.put("user_id",      userId);
        params.put("effective_user_ids", effectiveUserIds);
        return ResponseEntity.ok(ApiResponse.success(approvalService.getMyPendingLines(params)));
    }

    @PostMapping("/lines/{lineId}/process")
    public ResponseEntity<ApiResponse<Void>> processApproval(
            @PathVariable Long lineId,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        String action = (String) body.get("action");
        if (!List.of("approved", "rejected").contains(action))
            return ResponseEntity.status(400).body(ApiResponse.error("액션은 approved 또는 rejected여야 합니다."));

        Map<String, Object> params = new HashMap<>(body);
        params.put("line_id",     lineId);
        params.put("company_code", companyCode);
        params.put("user_id",     userId);
        try {
            approvalService.processApproval(params);
            String msg = "approved".equals(action) ? "승인 처리되었습니다." : "반려 처리되었습니다.";
            return ResponseEntity.ok(ApiResponse.success(null, msg));
        } catch (IllegalArgumentException e) {
            int status = e.getMessage().contains("찾을 수 없") ? 404 : 400;
            if (e.getMessage().contains("결재자로 지정")) status = 403;
            return ResponseEntity.status(status).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("결재 처리 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("결재 처리 중 오류가 발생했습니다."));
        }
    }

    // ═══════════════════════════════════════════════════════════════
    // approval_proxy_settings
    // ═══════════════════════════════════════════════════════════════

    // /proxy-settings/check/:userId 가 /{id} 보다 먼저 매핑되어야 하므로 먼저 선언
    @GetMapping("/proxy-settings/check/{targetUserId}")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> checkActiveProxy(
            @PathVariable String targetUserId,
            @RequestAttribute("company_code") String companyCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("user_id",      targetUserId);
        params.put("company_code", companyCode);
        return ResponseEntity.ok(ApiResponse.success(approvalService.checkActiveProxy(params)));
    }

    @GetMapping("/proxy-settings")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getProxySettings(
            @RequestAttribute("company_code") String companyCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("company_code", companyCode);
        return ResponseEntity.ok(ApiResponse.success(approvalService.getProxySettings(params)));
    }

    @PostMapping("/proxy-settings")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createProxySetting(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode) {
        body.put("company_code", companyCode);
        try {
            return ResponseEntity.status(HttpStatus.CREATED)
                    .body(ApiResponse.success(approvalService.createProxySetting(body), "대결 위임이 생성되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("대결 위임 생성 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("대결 위임 생성 중 오류가 발생했습니다."));
        }
    }

    @PutMapping("/proxy-settings/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateProxySetting(
            @PathVariable Long id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode) {
        body.put("id",          id);
        body.put("company_code", companyCode);
        try {
            return ResponseEntity.ok(ApiResponse.success(approvalService.updateProxySetting(body), "대결 위임이 수정되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("대결 위임 수정 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("대결 위임 수정 중 오류가 발생했습니다."));
        }
    }

    @DeleteMapping("/proxy-settings/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteProxySetting(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",          id);
        params.put("company_code", companyCode);
        try {
            approvalService.deleteProxySetting(params);
            return ResponseEntity.ok(ApiResponse.success(null, "대결 위임이 삭제되었습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("대결 위임 삭제 오류", e);
            return ResponseEntity.status(500).body(ApiResponse.error("대결 위임 삭제 중 오류가 발생했습니다."));
        }
    }
}
