package com.erp.controller;

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

import java.time.Instant;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/ddl")
@RequiredArgsConstructor
@Slf4j
public class DdlController {

    private final DdlService ddlService;

    // ─────────────────────────────────────────────────────────────────────────
    // DDL 실행 (SUPER_ADMIN 전용)
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * POST /api/ddl/tables - 새 테이블 생성
     */
    @PostMapping("/tables")
    public ResponseEntity<ApiResponse<?>> createTable(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role,
            @RequestAttribute("user_id") String userId,
            @RequestBody Map<String, Object> body) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        String tableName = (String) body.get("table_name");
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> columns = (List<Map<String, Object>>) body.get("columns");
        String description = (String) body.get("description");

        if (tableName == null || tableName.isBlank() || columns == null || columns.isEmpty()) {
            return ResponseEntity.status(400)
                .body(ApiResponse.error("테이블명과 최소 1개의 컬럼이 필요합니다."));
        }

        Map<String, Object> result = ddlService.createTable(tableName, columns, companyCode, userId, description);

        if (Boolean.TRUE.equals(result.get("success"))) {
            return ResponseEntity.ok(ApiResponse.success(Map.of(
                "table_name",    result.get("table_name"),
                "column_count",  result.get("column_count"),
                "executed_query", result.get("executed_query")
            ), (String) result.get("message")));
        }
        return ResponseEntity.status(400).body(ApiResponse.error((String) result.get("message")));
    }

    /**
     * POST /api/ddl/tables/{tableName}/columns - 컬럼 추가
     */
    @PostMapping("/tables/{tableName}/columns")
    public ResponseEntity<ApiResponse<?>> addColumn(
            @PathVariable String tableName,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role,
            @RequestAttribute("user_id") String userId,
            @RequestBody Map<String, Object> body) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        @SuppressWarnings("unchecked")
        Map<String, Object> column = (Map<String, Object>) body.get("column");
        if (column == null || column.get("name") == null
                || column.get("name").toString().isBlank()) {
            return ResponseEntity.status(400).body(ApiResponse.error("컬럼명이 필요합니다."));
        }

        Map<String, Object> result = ddlService.addColumn(tableName, column, companyCode, userId);

        if (Boolean.TRUE.equals(result.get("success"))) {
            return ResponseEntity.ok(ApiResponse.success(Map.of(
                "table_name",    result.get("table_name"),
                "column_name",   result.get("column_name"),
                "executed_query", result.get("executed_query")
            ), (String) result.get("message")));
        }
        return ResponseEntity.status(400).body(ApiResponse.error((String) result.get("message")));
    }

    /**
     * DELETE /api/ddl/tables/{tableName}/columns/{columnName} - 컬럼 삭제
     */
    @DeleteMapping("/tables/{tableName}/columns/{columnName}")
    public ResponseEntity<ApiResponse<?>> dropColumn(
            @PathVariable String tableName,
            @PathVariable String columnName,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role,
            @RequestAttribute("user_id") String userId) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        Map<String, Object> result = ddlService.dropColumn(tableName, columnName, companyCode, userId);

        if (Boolean.TRUE.equals(result.get("success"))) {
            return ResponseEntity.ok(ApiResponse.success(Map.of(
                "table_name",     result.get("table_name"),
                "column_name",    result.get("column_name"),
                "executed_query", result.get("executed_query")
            ), (String) result.get("message")));
        }
        return ResponseEntity.status(400).body(ApiResponse.error((String) result.get("message")));
    }

    /**
     * DELETE /api/ddl/tables/{tableName} - 테이블 삭제
     */
    @DeleteMapping("/tables/{tableName}")
    public ResponseEntity<ApiResponse<?>> dropTable(
            @PathVariable String tableName,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role,
            @RequestAttribute("user_id") String userId) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        Map<String, Object> result = ddlService.dropTable(tableName, companyCode, userId);

        if (Boolean.TRUE.equals(result.get("success"))) {
            return ResponseEntity.ok(ApiResponse.success(Map.of(
                "table_name",    result.get("table_name"),
                "executed_query", result.get("executed_query")
            ), (String) result.get("message")));
        }
        return ResponseEntity.status(400).body(ApiResponse.error((String) result.get("message")));
    }

    /**
     * POST /api/ddl/validate/table - 테이블 생성 사전 검증 (실제 생성 없음)
     */
    @PostMapping("/validate/table")
    public ResponseEntity<ApiResponse<?>> validateTableCreation(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role,
            @RequestBody Map<String, Object> body) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        String tableName = (String) body.get("table_name");
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> columns = (List<Map<String, Object>>) body.get("columns");

        if (tableName == null || columns == null) {
            return ResponseEntity.status(400)
                .body(ApiResponse.error("테이블명과 컬럼 정보가 필요합니다."));
        }

        Map<String, Object> result = ddlService.validateTableCreation(tableName, columns);
        return ResponseEntity.ok(ApiResponse.success(result, "검증 완료"));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 로그 및 모니터링
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * GET /api/ddl/logs - DDL 실행 로그 조회
     */
    @GetMapping("/logs")
    public ResponseEntity<ApiResponse<?>> getDdlLogs(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role,
            @RequestParam(required = false, defaultValue = "50") int limit,
            @RequestParam(required = false) String userId,
            @RequestParam(required = false) String ddlType) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        List<Map<String, Object>> logs = ddlService.getDdlLogs(limit, userId, ddlType);
        return ResponseEntity.ok(ApiResponse.success(
            Map.of("logs", logs, "total", logs.size()), "DDL 로그 조회 성공"));
    }

    /**
     * GET /api/ddl/statistics - DDL 실행 통계 조회
     */
    @GetMapping("/statistics")
    public ResponseEntity<ApiResponse<?>> getDdlStatistics(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role,
            @RequestParam(required = false) String fromDate,
            @RequestParam(required = false) String toDate) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        Map<String, Object> statistics = ddlService.getDdlStatistics(fromDate, toDate);
        return ResponseEntity.ok(ApiResponse.success(statistics, "DDL 통계 조회 성공"));
    }

    /**
     * GET /api/ddl/tables/{tableName}/history - 테이블 DDL 히스토리 조회
     */
    @GetMapping("/tables/{tableName}/history")
    public ResponseEntity<ApiResponse<?>> getTableDdlHistory(
            @PathVariable String tableName,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        List<Map<String, Object>> history = ddlService.getTableDdlHistory(tableName);
        return ResponseEntity.ok(ApiResponse.success(
            Map.of("table_name", tableName, "history", history, "total", history.size()),
            "테이블 DDL 히스토리 조회 성공"));
    }

    /**
     * GET /api/ddl/tables/{tableName}/info - 테이블 정보 조회
     */
    @GetMapping("/tables/{tableName}/info")
    public ResponseEntity<ApiResponse<?>> getTableInfo(
            @PathVariable String tableName,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        Map<String, Object> tableInfo = ddlService.getTableInfo(tableName);
        if (tableInfo == null) {
            return ResponseEntity.status(404)
                .body(ApiResponse.error("테이블 '" + tableName + "'을 찾을 수 없습니다."));
        }
        return ResponseEntity.ok(ApiResponse.success(tableInfo, "테이블 정보 조회 성공"));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 시스템 관리
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * DELETE /api/ddl/logs/cleanup - 오래된 DDL 로그 정리
     * NOTE: /logs/cleanup 은 /logs/{id} 보다 우선 매칭 (리터럴 세그먼트 우선)
     */
    @DeleteMapping("/logs/cleanup")
    public ResponseEntity<ApiResponse<?>> cleanupOldLogs(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role,
            @RequestParam(required = false, defaultValue = "90") int retentionDays) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        int deletedCount = ddlService.cleanupOldLogs(retentionDays);
        return ResponseEntity.ok(ApiResponse.success(
            Map.of("deleted_count", deletedCount, "retention_days", retentionDays),
            deletedCount + "개의 오래된 DDL 로그가 삭제되었습니다."));
    }

    /**
     * GET /api/ddl/info - DDL 서비스 정보
     */
    @GetMapping("/info")
    public ResponseEntity<ApiResponse<?>> getInfo(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute(value = "role", required = false) String role) {

        if (!isSuperAdmin(companyCode, role)) {
            return ResponseEntity.status(403).body(ApiResponse.error("최고 관리자(SUPER_ADMIN) 권한이 필요합니다."));
        }

        return ResponseEntity.ok(ApiResponse.success(Map.of(
            "service", "DDL Execution Service",
            "version", "1.0.0",
            "description", "PostgreSQL 테이블 및 컬럼 동적 생성 서비스",
            "requirements", Map.of(
                "authentication", "Bearer Token 필요",
                "authorization", "회사코드 '*'인 SUPER_ADMIN만 접근 가능",
                "safety", "모든 DDL 실행은 안전성 검증 후 수행",
                "logging", "모든 DDL 실행은 감사 로그에 기록"
            ),
            "endpoints", Map.of(
                "create_table",    "POST /api/ddl/tables",
                "add_column",      "POST /api/ddl/tables/{tableName}/columns",
                "drop_table",      "DELETE /api/ddl/tables/{tableName}",
                "validate",       "POST /api/ddl/validate/table",
                "logs",           "GET /api/ddl/logs",
                "statistics",     "GET /api/ddl/statistics",
                "history",        "GET /api/ddl/tables/{tableName}/history",
                "table_info",      "GET /api/ddl/tables/{tableName}/info",
                "cleanup",        "DELETE /api/ddl/logs/cleanup"
            )
        ), "DDL 서비스 정보"));
    }

    /**
     * GET /api/ddl/health - 헬스체크 (인증만 확인, SUPER_ADMIN 불필요)
     */
    @GetMapping("/health")
    public ResponseEntity<ApiResponse<?>> health() {
        return ResponseEntity.ok(ApiResponse.success(Map.of(
            "status",    "healthy",
            "timestamp", Instant.now().toString(),
            "checks",    Map.of("service", "operational")
        ), "DDL 서비스 정상"));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 내부 유틸
    // ─────────────────────────────────────────────────────────────────────────

    private boolean isSuperAdmin(String companyCode, String role) {
        // company_code 가 '*' 이고 role 이 SUPER_ADMIN 둘 다 충족해야 통과 (이중 체크).
        // 토큰 변조 또는 회사코드만으로 super 권한이 발급되는 사고 방지.
        return "*".equals(companyCode) && "SUPER_ADMIN".equals(role);
    }
}
