package com.erp.controller;

import com.erp.dto.ApiResponse;
import com.erp.service.DataflowService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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/dataflow")
@RequiredArgsConstructor
@Slf4j
public class DataflowController {

    private final DataflowService dataflowService;

    // ═══════════════════════════════════════════════════════════════════
    // table-relationships
    // ═══════════════════════════════════════════════════════════════════

    /**
     * POST /api/dataflow/table-relationships
     */
    @PostMapping("/table-relationships")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createTableRelationship(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @RequestBody Map<String, Object> body) {

        String relName  = str(body.get("relationship_name"));
        String fromTbl  = str(body.get("from_table_name"));
        String fromCol  = str(body.get("from_column_name"));
        String toTbl    = str(body.get("to_table_name"));
        String toCol    = str(body.get("to_column_name"));

        if (blank(relName) || blank(fromTbl) || blank(fromCol) || blank(toTbl) || blank(toCol)) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("필수 필드가 누락되었습니다. (relationshipName, fromTableName, fromColumnName, toTableName, toColumnName)"));
        }

        try {
            Map<String, Object> created = dataflowService.insertTableRelationship(body, companyCode, userId);
            return ResponseEntity.status(201)
                    .body(ApiResponse.success(created, "테이블 관계가 성공적으로 생성되었습니다."));
        } 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("테이블 관계 생성 중 오류가 발생했습니다."));
        }
    }

    /**
     * GET /api/dataflow/table-relationships
     */
    @GetMapping("/table-relationships")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getTableRelationshipList(
            @RequestAttribute("company_code") String companyCode) {
        try {
            return ResponseEntity.ok(ApiResponse.success(
                    dataflowService.getTableRelationshipList(companyCode),
                    "테이블 관계 목록을 성공적으로 조회했습니다."));
        } catch (Exception e) {
            log.error("테이블 관계 목록 조회 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("테이블 관계 목록 조회 중 오류가 발생했습니다."));
        }
    }

    /**
     * GET /api/dataflow/table-relationships/:relationshipId
     */
    @GetMapping("/table-relationships/{relationshipId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getTableRelationshipInfo(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int relationshipId) {
        try {
            Map<String, Object> rel = dataflowService.getTableRelationshipInfo(relationshipId, companyCode);
            if (rel == null) {
                return ResponseEntity.status(404).body(ApiResponse.error("테이블 관계를 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(rel, "테이블 관계를 성공적으로 조회했습니다."));
        } catch (Exception e) {
            log.error("테이블 관계 조회 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("테이블 관계 조회 중 오류가 발생했습니다."));
        }
    }

    /**
     * PUT /api/dataflow/table-relationships/:relationshipId
     */
    @PutMapping("/table-relationships/{relationshipId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateTableRelationship(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @PathVariable int relationshipId,
            @RequestBody Map<String, Object> body) {
        try {
            Map<String, Object> updated = dataflowService.updateTableRelationship(
                    relationshipId, body, companyCode, userId);
            if (updated == null) {
                return ResponseEntity.status(404).body(ApiResponse.error("테이블 관계를 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(updated, "테이블 관계가 성공적으로 수정되었습니다."));
        } catch (Exception e) {
            log.error("테이블 관계 수정 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("테이블 관계 수정 중 오류가 발생했습니다."));
        }
    }

    /**
     * DELETE /api/dataflow/table-relationships/:relationshipId
     */
    @DeleteMapping("/table-relationships/{relationshipId}")
    public ResponseEntity<ApiResponse<Void>> deleteTableRelationship(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int relationshipId) {
        try {
            boolean deleted = dataflowService.deleteTableRelationship(relationshipId, companyCode);
            if (!deleted) {
                return ResponseEntity.status(404).body(ApiResponse.error("테이블 관계를 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(null, "테이블 관계가 성공적으로 삭제되었습니다."));
        } catch (Exception e) {
            log.error("테이블 관계 삭제 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("테이블 관계 삭제 중 오류가 발생했습니다."));
        }
    }

    // ═══════════════════════════════════════════════════════════════════
    // data-links
    // ═══════════════════════════════════════════════════════════════════

    /**
     * POST /api/dataflow/data-links
     */
    @PostMapping("/data-links")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createDataLink(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @RequestBody Map<String, Object> body) {

        if (body.get("relationship_id") == null || blank(str(body.get("from_table_name")))
                || blank(str(body.get("from_column_name"))) || blank(str(body.get("to_table_name")))
                || blank(str(body.get("to_column_name")))   || blank(str(body.get("connection_type")))) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("필수 필드가 누락되었습니다."));
        }

        try {
            Map<String, Object> bridge = dataflowService.insertDataLink(body, companyCode, userId);
            return ResponseEntity.status(201)
                    .body(ApiResponse.success(bridge, "데이터 연결이 성공적으로 생성되었습니다."));
        } catch (Exception e) {
            log.error("데이터 연결 생성 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("데이터 연결 생성 중 오류가 발생했습니다."));
        }
    }

    /**
     * GET /api/dataflow/data-links/relationship/:relationshipId
     */
    @GetMapping("/data-links/relationship/{relationshipId}")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDataLinkList(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int relationshipId) {
        try {
            return ResponseEntity.ok(ApiResponse.success(
                    dataflowService.getDataLinkList(relationshipId, companyCode),
                    "연결된 데이터를 성공적으로 조회했습니다."));
        } catch (Exception e) {
            log.error("연결 데이터 조회 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("연결된 데이터 조회 중 오류가 발생했습니다."));
        }
    }

    /**
     * DELETE /api/dataflow/data-links/:bridgeId
     */
    @DeleteMapping("/data-links/{bridgeId}")
    public ResponseEntity<ApiResponse<Void>> deleteDataLink(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @PathVariable int bridgeId) {
        try {
            dataflowService.deleteDataLink(bridgeId, companyCode, userId);
            return ResponseEntity.ok(ApiResponse.success(null, "데이터 연결이 성공적으로 삭제되었습니다."));
        } catch (Exception e) {
            log.error("데이터 연결 삭제 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("데이터 연결 삭제 중 오류가 발생했습니다."));
        }
    }

    // ═══════════════════════════════════════════════════════════════════
    // table-data
    // ═══════════════════════════════════════════════════════════════════

    /**
     * GET /api/dataflow/table-data/:tableName
     */
    @GetMapping("/table-data/{tableName}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getTableData(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable String tableName,
            @RequestParam(defaultValue = "1")  int    page,
            @RequestParam(defaultValue = "10") int    limit,
            @RequestParam(defaultValue = "")   String search,
            @RequestParam(defaultValue = "")   String searchColumn) {
        try {
            Map<String, Object> result = dataflowService.getTableDataList(
                    tableName, page, limit, search, searchColumn, companyCode);
            return ResponseEntity.ok(ApiResponse.success(result, "테이블 데이터를 성공적으로 조회했습니다."));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("테이블 데이터 조회 실패: {}", tableName, e);
            return ResponseEntity.status(500).body(ApiResponse.error("테이블 데이터 조회 중 오류가 발생했습니다."));
        }
    }

    // ═══════════════════════════════════════════════════════════════════
    // diagrams
    // ═══════════════════════════════════════════════════════════════════

    /**
     * GET /api/dataflow/diagrams
     */
    @GetMapping("/diagrams")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getDiagramList(
            @RequestAttribute("company_code") String companyCode,
            @RequestParam(defaultValue = "1")  int    page,
            @RequestParam(defaultValue = "20") int    size,
            @RequestParam(defaultValue = "")   String searchTerm) {
        try {
            return ResponseEntity.ok(ApiResponse.success(
                    dataflowService.getDiagramList(companyCode, page, size, searchTerm),
                    "관계도 목록을 성공적으로 조회했습니다."));
        } catch (Exception e) {
            log.error("관계도 목록 조회 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("관계도 목록 조회 중 오류가 발생했습니다."));
        }
    }

    /**
     * GET /api/dataflow/diagrams/name/:diagramName/relationships
     * ※ /{diagramId}/relationships 보다 먼저 선언해야 "name" 세그먼트가 우선 매핑됨
     */
    @GetMapping("/diagrams/name/{diagramName}/relationships")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDiagramRelationshipList(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable String diagramName) {
        try {
            return ResponseEntity.ok(ApiResponse.success(
                    dataflowService.getDiagramRelationshipList(
                            companyCode, java.net.URLDecoder.decode(diagramName, "UTF-8")),
                    "관계도 관계를 성공적으로 조회했습니다."));
        } catch (Exception e) {
            log.error("관계도 관계 조회 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("관계도 관계 조회 중 오류가 발생했습니다."));
        }
    }

    /**
     * GET /api/dataflow/diagrams/:diagramId/relationships
     */
    @GetMapping("/diagrams/{diagramId}/relationships")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDiagramRelationshipListByDiagramId(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int diagramId) {
        try {
            return ResponseEntity.ok(ApiResponse.success(
                    dataflowService.getDiagramRelationshipListByDiagramId(companyCode, diagramId),
                    "관계도 관계 목록을 성공적으로 조회했습니다."));
        } catch (Exception e) {
            log.error("관계도 관계 조회 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("관계도 관계 조회에 실패했습니다."));
        }
    }

    /**
     * POST /api/dataflow/diagrams/:diagramName/copy
     */
    @PostMapping("/diagrams/{diagramName}/copy")
    public ResponseEntity<ApiResponse<Map<String, Object>>> copyDiagram(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable String diagramName) {
        try {
            String decoded       = java.net.URLDecoder.decode(diagramName, "UTF-8");
            String newDiagramName = dataflowService.copyDiagram(companyCode, decoded);
            Map<String, Object> data = new HashMap<>();
            data.put("new_diagram_name", newDiagramName);
            return ResponseEntity.ok(ApiResponse.success(data, "관계도가 성공적으로 복사되었습니다."));
        } 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("관계도 복사에 실패했습니다."));
        }
    }

    /**
     * DELETE /api/dataflow/diagrams/:diagramName
     */
    @DeleteMapping("/diagrams/{diagramName}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> deleteDiagram(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable String diagramName) {
        try {
            String decoded    = java.net.URLDecoder.decode(diagramName, "UTF-8");
            int deletedCount = dataflowService.deleteDiagram(companyCode, decoded);
            Map<String, Object> data = new HashMap<>();
            data.put("deleted_count", deletedCount);
            return ResponseEntity.ok(ApiResponse.success(data, "관계도가 성공적으로 삭제되었습니다."));
        } catch (Exception e) {
            log.error("관계도 삭제 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("관계도 삭제에 실패했습니다."));
        }
    }

    /**
     * GET /api/dataflow/relationships/:relationshipId/diagram
     * (하위 호환성)
     */
    @GetMapping("/relationships/{relationshipId}/diagram")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDiagramRelationshipListByRelationshipId(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int relationshipId) {
        try {
            return ResponseEntity.ok(ApiResponse.success(
                    dataflowService.getDiagramRelationshipListByRelationshipId(companyCode, relationshipId),
                    "관계도 관계 목록을 성공적으로 조회했습니다."));
        } catch (Exception e) {
            log.error("관계도 관계 조회 실패", e);
            return ResponseEntity.status(500).body(ApiResponse.error("관계도 관계 조회에 실패했습니다."));
        }
    }

    // ═══════════════════════════════════════════════════════════════════
    // conditional connections (stub — conditionalConnectionController 미구현)
    // ═══════════════════════════════════════════════════════════════════

    /**
     * POST /api/dataflow/diagrams/:diagramId/test-conditions
     */
    @PostMapping("/diagrams/{diagramId}/test-conditions")
    public ResponseEntity<ApiResponse<Map<String, Object>>> testConditionalConnection(
            @PathVariable int diagramId,
            @RequestBody(required = false) Map<String, Object> body) {
        Map<String, Object> result = new HashMap<>();
        result.put("diagram_id", diagramId);
        result.put("tested",    true);
        return ResponseEntity.ok(ApiResponse.success(result, "조건 테스트가 완료되었습니다."));
    }

    /**
     * POST /api/dataflow/diagrams/:diagramId/execute-actions
     */
    @PostMapping("/diagrams/{diagramId}/execute-actions")
    public ResponseEntity<ApiResponse<Map<String, Object>>> executeConditionalActions(
            @PathVariable int diagramId,
            @RequestBody(required = false) Map<String, Object> body) {
        Map<String, Object> result = new HashMap<>();
        result.put("diagram_id", diagramId);
        result.put("executed",  true);
        return ResponseEntity.ok(ApiResponse.success(result, "액션이 성공적으로 실행되었습니다."));
    }

    // ═══════════════════════════════════════════════════════════════════
    // helpers
    // ═══════════════════════════════════════════════════════════════════

    private String str(Object val)      { return val == null ? null : val.toString(); }
    private boolean blank(String val)   { return val == null || val.isBlank(); }
}
