package com.erp.controller;

import com.erp.dto.ApiResponse;
import com.erp.service.EntitySearchService;
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.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Entity Search / Options / Distinct 통합 컨트롤러
 *
 * Node.js 라우트 대응:
 *   GET /api/entity-search/:tableName        → searchEntity
 *   GET /api/entity/:tableName/options       → getEntityOptions
 *   GET /api/entity/:tableName/distinct/:col → getDistinctColumnValues
 */
@RestController
@RequiredArgsConstructor
@Slf4j
public class EntitySearchController {

    private final EntitySearchService entitySearchService;

    // ================================================================
    // GET /api/entity-search/{tableName}
    // ================================================================

    @GetMapping("/api/entity-search/{tableName}")
    public ResponseEntity<?> searchEntity(
            @PathVariable String tableName,
            @RequestParam(defaultValue = "")   String searchText,
            @RequestParam(defaultValue = "")   String searchFields,
            @RequestParam(defaultValue = "{}") String filterCondition,
            @RequestParam(defaultValue = "1")  String page,
            @RequestParam(defaultValue = "20") String limit,
            @RequestAttribute("company_code") String companyCode) {

        if (tableName == null || tableName.isBlank()
                || "undefined".equals(tableName) || "null".equals(tableName)) {
            return ResponseEntity.status(400).body(
                ApiResponse.error("테이블명이 지정되지 않았습니다. 컴포넌트 설정에서 sourceTable을 확인해주세요."));
        }

        Map<String, Object> params = new HashMap<>();
        params.put("table_name",       tableName);
        params.put("company_code",     companyCode);
        params.put("search_text",      searchText);
        params.put("search_fields",    searchFields);
        params.put("filter_condition", filterCondition);
        params.put("page",            page);
        params.put("limit",           limit);

        try {
            Map<String, Object> result = entitySearchService.searchEntity(params);
            // Node.js 응답 형식: { success, data, pagination } — pagination이 data와 같은 레벨
            Map<String, Object> response = new LinkedHashMap<>();
            response.put("success", true);
            response.put("data", result.get("data"));
            response.put("pagination", result.get("pagination"));
            return ResponseEntity.ok(response);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("엔티티 검색 오류 table={}", tableName, e);
            return ResponseEntity.status(500).body(ApiResponse.error(e.getMessage()));
        }
    }

    // ================================================================
    // GET /api/entity/{tableName}/options
    // ================================================================

    @GetMapping("/api/entity/{tableName}/options")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getEntityOptions(
            @PathVariable String tableName,
            @RequestParam(defaultValue = "id")   String value,
            @RequestParam(defaultValue = "name") String label,
            @RequestParam(required = false)      String fields,
            @RequestParam(required = false)      String filters,
            @RequestAttribute("company_code") String companyCode) {

        if (tableName == null || tableName.isBlank()
                || "undefined".equals(tableName) || "null".equals(tableName)) {
            return ResponseEntity.status(400).body(ApiResponse.error("테이블명이 지정되지 않았습니다."));
        }

        Map<String, Object> params = new HashMap<>();
        params.put("table_name",   tableName);
        params.put("company_code", companyCode);
        params.put("value",       value);
        params.put("label",       label);
        params.put("fields",      fields);
        params.put("filters",     filters);

        try {
            return ResponseEntity.ok(ApiResponse.success(entitySearchService.getEntityOptions(params)));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("엔티티 옵션 조회 오류 table={}", tableName, e);
            return ResponseEntity.status(500).body(ApiResponse.error(e.getMessage()));
        }
    }

    // ================================================================
    // GET /api/entity/{tableName}/distinct/{columnName}
    // ================================================================

    @GetMapping("/api/entity/{tableName}/distinct/{columnName}")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDistinctColumnValues(
            @PathVariable String tableName,
            @PathVariable String columnName,
            @RequestParam(required = false) String labelColumn,
            @RequestParam(required = false) String filters,
            @RequestAttribute("company_code") String companyCode) {

        if (tableName == null || tableName.isBlank()
                || "undefined".equals(tableName) || "null".equals(tableName)) {
            return ResponseEntity.status(400).body(ApiResponse.error("테이블명이 지정되지 않았습니다."));
        }
        if (columnName == null || columnName.isBlank()
                || "undefined".equals(columnName) || "null".equals(columnName)) {
            return ResponseEntity.status(400).body(ApiResponse.error("컬럼명이 지정되지 않았습니다."));
        }

        Map<String, Object> params = new HashMap<>();
        params.put("table_name",   tableName);
        params.put("column_name",  columnName);
        params.put("company_code", companyCode);
        params.put("label_column", labelColumn);
        params.put("filters",     filters);

        try {
            return ResponseEntity.ok(ApiResponse.success(entitySearchService.getDistinctColumnValues(params)));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("컬럼 DISTINCT 조회 오류 table={} column={}", tableName, columnName, e);
            return ResponseEntity.status(500).body(ApiResponse.error(e.getMessage()));
        }
    }
}
