package com.erp.controller;

import com.erp.dto.ApiResponse;
import com.erp.service.ScreenEmbeddingService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
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;

/**
 * 화면 임베딩 및 데이터 전달 시스템 컨트롤러
 *
 * GET    /api/screen-embedding               - 목록 조회 (?parentScreenId)
 * GET    /api/screen-embedding/{id}          - 상세 조회
 * POST   /api/screen-embedding               - 생성
 * PUT    /api/screen-embedding/{id}          - 수정
 * DELETE /api/screen-embedding/{id}          - 삭제
 *
 * GET    /api/screen-data-transfer           - 조회 (?sourceScreenId&targetScreenId)
 * POST   /api/screen-data-transfer           - 생성
 * PUT    /api/screen-data-transfer/{id}      - 수정
 * DELETE /api/screen-data-transfer/{id}      - 삭제
 *
 * GET    /api/screen-split-panel/{screenId}  - 조회
 * POST   /api/screen-split-panel             - 생성
 * PUT    /api/screen-split-panel/{id}        - 수정
 * DELETE /api/screen-split-panel/{id}        - 삭제
 */
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
@Slf4j
public class ScreenEmbeddingController {

    private final ScreenEmbeddingService service;

    // ══════════════════════════════════════════════════════════════
    // Screen Embedding
    // ══════════════════════════════════════════════════════════════

    @GetMapping("/screen-embedding")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getScreenEmbeddingList(
            @RequestParam(required = false) Long parentScreenId,
            @RequestAttribute("company_code") String companyCode) {
        if (parentScreenId == null) {
            return ResponseEntity.status(400)
                    .body(ApiResponse.error("부모 화면 ID가 필요합니다."));
        }
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("parent_screen_id", parentScreenId);
            params.put("company_code",    companyCode);
            return ResponseEntity.ok(ApiResponse.success(service.getScreenEmbeddingList(params)));
        } catch (Exception e) {
            log.error("화면 임베딩 목록 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 임베딩 목록 조회 중 오류가 발생했습니다."));
        }
    }

    @GetMapping("/screen-embedding/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getScreenEmbeddingInfo(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("id",          id);
            params.put("company_code", companyCode);
            Map<String, Object> result = service.getScreenEmbeddingInfo(params);
            if (result == null) {
                return ResponseEntity.status(404)
                        .body(ApiResponse.error("화면 임베딩 설정을 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("화면 임베딩 상세 조회 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 임베딩 상세 조회 중 오류가 발생했습니다."));
        }
    }

    @PostMapping("/screen-embedding")
    public ResponseEntity<ApiResponse<Map<String, Object>>> insertScreenEmbedding(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        if (body.get("parent_screen_id") == null || body.get("child_screen_id") == null
                || body.get("position") == null || body.get("mode") == null) {
            return ResponseEntity.status(400).body(ApiResponse.error("필수 필드가 누락되었습니다."));
        }
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            Map<String, Object> result = service.insertScreenEmbedding(body);
            return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(result));
        } catch (DuplicateKeyException e) {
            return ResponseEntity.status(409)
                    .body(ApiResponse.error("이미 동일한 임베딩 설정이 존재합니다."));
        } catch (Exception e) {
            log.error("화면 임베딩 생성 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 임베딩 생성 중 오류가 발생했습니다."));
        }
    }

    @PutMapping("/screen-embedding/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateScreenEmbedding(
            @PathVariable Long id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode) {
        if (body.get("position") == null && body.get("mode") == null && body.get("config") == null) {
            return ResponseEntity.status(400).body(ApiResponse.error("수정할 내용이 없습니다."));
        }
        body.put("id",          id);
        body.put("company_code", companyCode);
        try {
            Map<String, Object> result = service.updateScreenEmbedding(body);
            if (result == null) {
                return ResponseEntity.status(404)
                        .body(ApiResponse.error("화면 임베딩 설정을 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("화면 임베딩 수정 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 임베딩 수정 중 오류가 발생했습니다."));
        }
    }

    @DeleteMapping("/screen-embedding/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteScreenEmbedding(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",          id);
        params.put("company_code", companyCode);
        try {
            boolean deleted = service.deleteScreenEmbedding(params);
            if (!deleted) {
                return ResponseEntity.status(404)
                        .body(ApiResponse.error("화면 임베딩 설정을 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(null, "화면 임베딩이 삭제되었습니다."));
        } catch (Exception e) {
            log.error("화면 임베딩 삭제 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 임베딩 삭제 중 오류가 발생했습니다."));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // Screen Data Transfer
    // ══════════════════════════════════════════════════════════════

    @GetMapping("/screen-data-transfer")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getScreenDataTransferInfo(
            @RequestParam(required = false) Long sourceScreenId,
            @RequestParam(required = false) Long targetScreenId,
            @RequestAttribute("company_code") String companyCode) {
        if (sourceScreenId == null || targetScreenId == null) {
            return ResponseEntity.status(400)
                    .body(ApiResponse.error("소스 화면 ID와 타겟 화면 ID가 필요합니다."));
        }
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("source_screen_id", sourceScreenId);
            params.put("target_screen_id", targetScreenId);
            params.put("company_code",    companyCode);
            Map<String, Object> result = service.getScreenDataTransferInfo(params);
            if (result == null) {
                return ResponseEntity.status(404)
                        .body(ApiResponse.error("데이터 전달 설정을 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("데이터 전달 설정 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("데이터 전달 설정 조회 중 오류가 발생했습니다."));
        }
    }

    @PostMapping("/screen-data-transfer")
    public ResponseEntity<ApiResponse<Map<String, Object>>> insertScreenDataTransfer(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        if (body.get("source_screen_id") == null || body.get("target_screen_id") == null
                || body.get("data_receivers") == null) {
            return ResponseEntity.status(400).body(ApiResponse.error("필수 필드가 누락되었습니다."));
        }
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            Map<String, Object> result = service.insertScreenDataTransfer(body);
            return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(result));
        } catch (DuplicateKeyException e) {
            return ResponseEntity.status(409)
                    .body(ApiResponse.error("이미 동일한 데이터 전달 설정이 존재합니다."));
        } catch (Exception e) {
            log.error("데이터 전달 설정 생성 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("데이터 전달 설정 생성 중 오류가 발생했습니다."));
        }
    }

    @PutMapping("/screen-data-transfer/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateScreenDataTransfer(
            @PathVariable Long id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode) {
        if (body.get("data_receivers") == null && body.get("button_config") == null) {
            return ResponseEntity.status(400).body(ApiResponse.error("수정할 내용이 없습니다."));
        }
        body.put("id",          id);
        body.put("company_code", companyCode);
        try {
            Map<String, Object> result = service.updateScreenDataTransfer(body);
            if (result == null) {
                return ResponseEntity.status(404)
                        .body(ApiResponse.error("데이터 전달 설정을 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("데이터 전달 설정 수정 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("데이터 전달 설정 수정 중 오류가 발생했습니다."));
        }
    }

    @DeleteMapping("/screen-data-transfer/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteScreenDataTransfer(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",          id);
        params.put("company_code", companyCode);
        try {
            boolean deleted = service.deleteScreenDataTransfer(params);
            if (!deleted) {
                return ResponseEntity.status(404)
                        .body(ApiResponse.error("데이터 전달 설정을 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(null, "데이터 전달 설정이 삭제되었습니다."));
        } catch (Exception e) {
            log.error("데이터 전달 설정 삭제 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("데이터 전달 설정 삭제 중 오류가 발생했습니다."));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // Screen Split Panel
    // ══════════════════════════════════════════════════════════════

    @GetMapping("/screen-split-panel/{screenId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getScreenSplitPanelInfo(
            @PathVariable Long screenId,
            @RequestAttribute("company_code") String companyCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("screen_id",    screenId);
            params.put("company_code", companyCode);
            Map<String, Object> result = service.getScreenSplitPanelInfo(params);
            if (result == null) {
                return ResponseEntity.status(404)
                        .body(ApiResponse.error("분할 패널 설정을 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("분할 패널 설정 조회 실패: screenId={}", screenId, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("분할 패널 설정 조회 중 오류가 발생했습니다."));
        }
    }

    @PostMapping("/screen-split-panel")
    public ResponseEntity<ApiResponse<Map<String, Object>>> insertScreenSplitPanel(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        if (body.get("screen_id") == null || body.get("left_embedding") == null
                || body.get("right_embedding") == null || body.get("data_transfer") == null) {
            return ResponseEntity.status(400).body(ApiResponse.error("필수 필드가 누락되었습니다."));
        }
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            Map<String, Object> result = service.insertScreenSplitPanel(body);
            return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("분할 패널 설정 생성 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("분할 패널 설정 생성 중 오류가 발생했습니다."));
        }
    }

    @PutMapping("/screen-split-panel/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateScreenSplitPanel(
            @PathVariable Long id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode) {
        if (body.get("layout_config") == null) {
            return ResponseEntity.status(400).body(ApiResponse.error("수정할 내용이 없습니다."));
        }
        body.put("id",          id);
        body.put("company_code", companyCode);
        try {
            Map<String, Object> result = service.updateScreenSplitPanel(body);
            if (result == null) {
                return ResponseEntity.status(404)
                        .body(ApiResponse.error("분할 패널 설정을 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("분할 패널 설정 수정 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("분할 패널 설정 수정 중 오류가 발생했습니다."));
        }
    }

    @DeleteMapping("/screen-split-panel/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteScreenSplitPanel(
            @PathVariable Long id,
            @RequestAttribute("company_code") String companyCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",          id);
        params.put("company_code", companyCode);
        try {
            boolean deleted = service.deleteScreenSplitPanel(params);
            if (!deleted) {
                return ResponseEntity.status(404)
                        .body(ApiResponse.error("분할 패널 설정을 찾을 수 없습니다."));
            }
            return ResponseEntity.ok(ApiResponse.success(null, "분할 패널 설정이 삭제되었습니다."));
        } catch (Exception e) {
            log.error("분할 패널 설정 삭제 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("분할 패널 설정 삭제 중 오류가 발생했습니다."));
        }
    }
}
