package com.erp.controller;

import com.erp.dto.ApiResponse;
import com.erp.service.ScreenGroupService;
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;
import java.util.NoSuchElementException;

@RestController
@RequestMapping("/api/screen-groups")
@RequiredArgsConstructor
@Slf4j
public class ScreenGroupController {

    private final ScreenGroupService service;

    // ══════════════════════════════════════════════════════════════
    // Screen Groups — CRUD
    // ══════════════════════════════════════════════════════════════

    /** GET /api/screen-groups/groups */
    @GetMapping("/groups")
    public ResponseEntity<?> getScreenGroups(
            @RequestParam(required = false) String search,
            @RequestParam(required = false) String groupName,
            @RequestParam(required = false) Integer parentGroupId,
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "20") int size,
            @RequestParam(required = false) String filterCompanyCode,
            @RequestAttribute("company_code") String companyCode) {
        try {
            String effectiveCompanyCode = ("*".equals(companyCode) && filterCompanyCode != null)
                    ? filterCompanyCode : companyCode;

            Map<String, Object> params = new HashMap<>();
            params.put("company_code", effectiveCompanyCode);
            params.put("page", page);
            params.put("size", size);
            if (search       != null) params.put("search",        search);
            if (groupName    != null) params.put("group_name",     groupName);
            if (parentGroupId != null) params.put("parent_group_id", parentGroupId);

            // 페이지네이션 응답은 Node.js 동일 구조(total/page/size/totalPages) 유지
            return ResponseEntity.ok(service.getScreenGroups(params));
        } catch (Exception e) {
            log.error("화면 그룹 목록 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 그룹 목록 조회 중 오류가 발생했습니다"));
        }
    }

    /** GET /api/screen-groups/groups/:id */
    @GetMapping("/groups/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getScreenGroup(
            @PathVariable Integer 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> group = service.getScreenGroup(params);
            if (group == null) {
                return ResponseEntity.status(404).body(ApiResponse.error("화면 그룹을 찾을 수 없습니다"));
            }
            return ResponseEntity.ok(ApiResponse.success(group));
        } catch (Exception e) {
            log.error("화면 그룹 단건 조회 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 그룹 조회 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/groups */
    @PostMapping("/groups")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createScreenGroup(
            @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 {
            Map<String, Object> created = service.createScreenGroup(body);
            return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(created));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "화면 그룹 생성 중 오류가 발생했습니다"));
        } catch (Exception e) {
            log.error("화면 그룹 생성 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 그룹 생성 중 오류가 발생했습니다"));
        }
    }

    /** PUT /api/screen-groups/groups/:id */
    @PutMapping("/groups/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateScreenGroup(
            @PathVariable Integer id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("id",          id);
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            return ResponseEntity.ok(ApiResponse.success(service.updateScreenGroup(body)));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "화면 그룹을 찾을 수 없습니다"));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "화면 그룹 수정 중 오류가 발생했습니다"));
        } catch (Exception e) {
            log.error("화면 그룹 수정 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 그룹 수정 중 오류가 발생했습니다"));
        }
    }

    /** DELETE /api/screen-groups/groups/:id */
    @DeleteMapping("/groups/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteScreenGroup(
            @PathVariable Integer id,
            @RequestParam(required = false, defaultValue = "false") boolean deleteNumberingRules,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",                   id);
        params.put("company_code",          companyCode);
        params.put("user_id",               userId);
        params.put("delete_numbering_rules", deleteNumberingRules);
        try {
            service.deleteScreenGroup(params);
            return ResponseEntity.ok(ApiResponse.success(null, "화면 그룹이 삭제되었습니다"));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "화면 그룹을 찾을 수 없습니다"));
        } catch (SecurityException e) {
            return ResponseEntity.status(403).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "권한이 없습니다"));
        } catch (Exception e) {
            log.error("화면 그룹 삭제 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 그룹 삭제 중 오류가 발생했습니다"));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // Screen Group Screens
    // ══════════════════════════════════════════════════════════════

    /** POST /api/screen-groups/group-screens */
    @PostMapping("/group-screens")
    public ResponseEntity<ApiResponse<Map<String, Object>>> addScreenToGroup(
            @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(service.addScreenToGroup(body)));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "화면 그룹 연결 중 오류가 발생했습니다"));
        } catch (Exception e) {
            log.error("화면 그룹 화면 추가 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 그룹 화면 추가 중 오류가 발생했습니다"));
        }
    }

    /** PUT /api/screen-groups/group-screens/:id */
    @PutMapping("/group-screens/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateScreenInGroup(
            @PathVariable Integer id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("id",          id);
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            return ResponseEntity.ok(ApiResponse.success(service.updateScreenInGroup(body)));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "연결을 찾을 수 없습니다"));
        } catch (Exception e) {
            log.error("화면 그룹 화면 수정 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 그룹 화면 수정 중 오류가 발생했습니다"));
        }
    }

    /** DELETE /api/screen-groups/group-screens/:id */
    @DeleteMapping("/group-screens/{id}")
    public ResponseEntity<ApiResponse<Void>> removeScreenFromGroup(
            @PathVariable Integer id,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",          id);
        params.put("company_code", companyCode);
        params.put("user_id",      userId);
        try {
            service.removeScreenFromGroup(params);
            return ResponseEntity.ok(ApiResponse.success(null, "화면 그룹 연결이 해제되었습니다"));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "연결을 찾을 수 없습니다"));
        } catch (Exception e) {
            log.error("화면 그룹 화면 삭제 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면 그룹 화면 삭제 중 오류가 발생했습니다"));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // Field Joins
    // ══════════════════════════════════════════════════════════════

    /** GET /api/screen-groups/field-joins */
    @GetMapping("/field-joins")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getFieldJoins(
            @RequestParam(required = false) Integer groupId,
            @RequestParam(required = false) Integer screenId,
            @RequestAttribute("company_code") String companyCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("company_code", companyCode);
            if (groupId  != null) params.put("group_id",  groupId);
            if (screenId != null) params.put("screen_id", screenId);
            return ResponseEntity.ok(ApiResponse.success(service.getFieldJoins(params)));
        } catch (Exception e) {
            log.error("필드 조인 목록 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("필드 조인 목록 조회 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/field-joins */
    @PostMapping("/field-joins")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createFieldJoin(
            @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(service.createFieldJoin(body)));
        } catch (Exception e) {
            log.error("필드 조인 생성 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("필드 조인 생성 중 오류가 발생했습니다"));
        }
    }

    /** PUT /api/screen-groups/field-joins/:id */
    @PutMapping("/field-joins/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateFieldJoin(
            @PathVariable Integer id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("id",          id);
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            return ResponseEntity.ok(ApiResponse.success(service.updateFieldJoin(body)));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "필드 조인을 찾을 수 없습니다"));
        } catch (Exception e) {
            log.error("필드 조인 수정 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("필드 조인 수정 중 오류가 발생했습니다"));
        }
    }

    /** DELETE /api/screen-groups/field-joins/:id */
    @DeleteMapping("/field-joins/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteFieldJoin(
            @PathVariable Integer id,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",          id);
        params.put("company_code", companyCode);
        params.put("user_id",      userId);
        try {
            service.deleteFieldJoin(params);
            return ResponseEntity.ok(ApiResponse.success(null, "필드 조인이 삭제되었습니다"));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "필드 조인을 찾을 수 없습니다"));
        } catch (Exception e) {
            log.error("필드 조인 삭제 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("필드 조인 삭제 중 오류가 발생했습니다"));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // Data Flows
    // ══════════════════════════════════════════════════════════════

    /** GET /api/screen-groups/data-flows */
    @GetMapping("/data-flows")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDataFlows(
            @RequestParam(required = false) Integer groupId,
            @RequestParam(required = false) Integer screenId,
            @RequestAttribute("company_code") String companyCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("company_code", companyCode);
            if (groupId  != null) params.put("group_id",  groupId);
            if (screenId != null) params.put("screen_id", screenId);
            return ResponseEntity.ok(ApiResponse.success(service.getDataFlows(params)));
        } catch (Exception e) {
            log.error("데이터 흐름 목록 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("데이터 흐름 목록 조회 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/data-flows */
    @PostMapping("/data-flows")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createDataFlow(
            @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(service.createDataFlow(body)));
        } catch (Exception e) {
            log.error("데이터 흐름 생성 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("데이터 흐름 생성 중 오류가 발생했습니다"));
        }
    }

    /** PUT /api/screen-groups/data-flows/:id */
    @PutMapping("/data-flows/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateDataFlow(
            @PathVariable Integer id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("id",          id);
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            return ResponseEntity.ok(ApiResponse.success(service.updateDataFlow(body)));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "데이터 흐름을 찾을 수 없습니다"));
        } catch (Exception e) {
            log.error("데이터 흐름 수정 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("데이터 흐름 수정 중 오류가 발생했습니다"));
        }
    }

    /** DELETE /api/screen-groups/data-flows/:id */
    @DeleteMapping("/data-flows/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteDataFlow(
            @PathVariable Integer id,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",          id);
        params.put("company_code", companyCode);
        params.put("user_id",      userId);
        try {
            service.deleteDataFlow(params);
            return ResponseEntity.ok(ApiResponse.success(null, "데이터 흐름이 삭제되었습니다"));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "데이터 흐름을 찾을 수 없습니다"));
        } catch (Exception e) {
            log.error("데이터 흐름 삭제 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("데이터 흐름 삭제 중 오류가 발생했습니다"));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // Table Relations
    // ══════════════════════════════════════════════════════════════

    /** GET /api/screen-groups/table-relations */
    @GetMapping("/table-relations")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getTableRelations(
            @RequestParam(required = false) Integer groupId,
            @RequestParam(required = false) Integer screenId,
            @RequestAttribute("company_code") String companyCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("company_code", companyCode);
            if (groupId  != null) params.put("group_id",  groupId);
            if (screenId != null) params.put("screen_id", screenId);
            return ResponseEntity.ok(ApiResponse.success(service.getTableRelations(params)));
        } catch (Exception e) {
            log.error("화면-테이블 관계 목록 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면-테이블 관계 목록 조회 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/table-relations */
    @PostMapping("/table-relations")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createTableRelation(
            @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(service.createTableRelation(body)));
        } catch (Exception e) {
            log.error("화면-테이블 관계 생성 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면-테이블 관계 생성 중 오류가 발생했습니다"));
        }
    }

    /** PUT /api/screen-groups/table-relations/:id */
    @PutMapping("/table-relations/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateTableRelation(
            @PathVariable Integer id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("id",          id);
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            return ResponseEntity.ok(ApiResponse.success(service.updateTableRelation(body)));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "화면-테이블 관계를 찾을 수 없습니다"));
        } catch (Exception e) {
            log.error("화면-테이블 관계 수정 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면-테이블 관계 수정 중 오류가 발생했습니다"));
        }
    }

    /** DELETE /api/screen-groups/table-relations/:id */
    @DeleteMapping("/table-relations/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteTableRelation(
            @PathVariable Integer id,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",          id);
        params.put("company_code", companyCode);
        params.put("user_id",      userId);
        try {
            service.deleteTableRelation(params);
            return ResponseEntity.ok(ApiResponse.success(null, "화면-테이블 관계가 삭제되었습니다"));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "화면-테이블 관계를 찾을 수 없습니다"));
        } catch (Exception e) {
            log.error("화면-테이블 관계 삭제 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("화면-테이블 관계 삭제 중 오류가 발생했습니다"));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // Layout Summary
    // ══════════════════════════════════════════════════════════════

    /** GET /api/screen-groups/layout-summary/:screenId */
    @GetMapping("/layout-summary/{screenId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getScreenLayoutSummary(
            @PathVariable Integer screenId,
            @RequestAttribute("company_code") String companyCode) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("screen_id",    screenId);
            params.put("company_code", companyCode);
            return ResponseEntity.ok(ApiResponse.success(service.getScreenLayoutSummary(params)));
        } catch (Exception e) {
            log.error("레이아웃 요약 조회 실패: screenId={}", screenId, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("레이아웃 요약 조회 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/layout-summary/batch */
    @PostMapping("/layout-summary/batch")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getMultipleScreenLayoutSummary(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode) {
        try {
            @SuppressWarnings("unchecked")
            List<Integer> screenIds = (List<Integer>) body.get("screen_ids");
            return ResponseEntity.ok(ApiResponse.success(
                    service.getMultipleScreenLayoutSummary(screenIds)));
        } catch (Exception e) {
            log.error("다중 레이아웃 요약 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("다중 레이아웃 요약 조회 중 오류가 발생했습니다"));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // Sub Tables
    // ══════════════════════════════════════════════════════════════

    /** POST /api/screen-groups/sub-tables/batch */
    @PostMapping("/sub-tables/batch")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getScreenSubTables(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode) {
        try {
            @SuppressWarnings("unchecked")
            List<Integer> screenIds = (List<Integer>) body.get("screen_ids");
            return ResponseEntity.ok(ApiResponse.success(
                    service.getScreenSubTables(screenIds)));
        } catch (Exception e) {
            log.error("서브 테이블 배치 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("서브 테이블 조회 중 오류가 발생했습니다"));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // Sync
    // ══════════════════════════════════════════════════════════════

    /** GET /api/screen-groups/sync/status */
    @GetMapping("/sync/status")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getSyncStatus(
            @RequestParam(required = false) String filterCompanyCode,
            @RequestAttribute("company_code") String companyCode) {
        try {
            String effectiveCompanyCode = ("*".equals(companyCode) && filterCompanyCode != null)
                    ? filterCompanyCode : companyCode;
            return ResponseEntity.ok(ApiResponse.success(service.getSyncStatus(effectiveCompanyCode)));
        } catch (Exception e) {
            log.error("동기화 상태 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("동기화 상태 조회 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/sync/screen-to-menu */
    @PostMapping("/sync/screen-to-menu")
    public ResponseEntity<ApiResponse<Map<String, Object>>> syncScreenGroupsToMenu(
            @RequestBody(required = false) Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        try {
            String targetCompanyCode = companyCode;
            if (body != null && body.get("company_code") != null) {
                targetCompanyCode = (String) body.get("company_code");
            }
            Map<String, Object> result = service.syncScreenGroupsToMenu(targetCompanyCode, userId);
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("화면관리 → 메뉴 동기화 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("동기화 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/sync/menu-to-screen */
    @PostMapping("/sync/menu-to-screen")
    public ResponseEntity<ApiResponse<Map<String, Object>>> syncMenuToScreenGroups(
            @RequestBody(required = false) Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        try {
            String targetCompanyCode = companyCode;
            if (body != null && body.get("company_code") != null) {
                targetCompanyCode = (String) body.get("company_code");
            }
            Map<String, Object> result = service.syncMenuToScreenGroups(targetCompanyCode, userId);
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("메뉴 → 화면관리 동기화 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("동기화 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/sync/all */
    @PostMapping("/sync/all")
    public ResponseEntity<ApiResponse<Map<String, Object>>> syncAllCompanies(
            @RequestAttribute("user_id") String userId) {
        try {
            return ResponseEntity.ok(ApiResponse.success(service.syncAllCompanies(userId)));
        } catch (Exception e) {
            log.error("전체 회사 동기화 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("전체 회사 동기화 중 오류가 발생했습니다"));
        }
    }

    // ══════════════════════════════════════════════════════════════
    // POP Groups
    // ══════════════════════════════════════════════════════════════

    /** GET /api/screen-groups/pop/groups */
    @GetMapping("/pop/groups")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getPopScreenGroups(
            @RequestParam(required = false) String filterCompanyCode,
            @RequestAttribute("company_code") String companyCode) {
        try {
            String effectiveCompanyCode = ("*".equals(companyCode) && filterCompanyCode != null)
                    ? filterCompanyCode : companyCode;
            Map<String, Object> params = new HashMap<>();
            params.put("company_code", effectiveCompanyCode);
            return ResponseEntity.ok(ApiResponse.success(service.getPopScreenGroups(params)));
        } catch (Exception e) {
            log.error("POP 화면 그룹 목록 조회 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("POP 화면 그룹 목록 조회 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/pop/groups */
    @PostMapping("/pop/groups")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createPopScreenGroup(
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("user_company_code", companyCode);
        body.put("user_id",          userId);
        try {
            return ResponseEntity.status(HttpStatus.CREATED)
                    .body(ApiResponse.success(service.createPopScreenGroup(body)));
        } catch (SecurityException e) {
            return ResponseEntity.status(403).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "권한이 없습니다"));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "POP 화면 그룹 생성 중 오류가 발생했습니다"));
        } catch (Exception e) {
            log.error("POP 화면 그룹 생성 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("POP 화면 그룹 생성 중 오류가 발생했습니다"));
        }
    }

    /** PUT /api/screen-groups/pop/groups/:id */
    @PutMapping("/pop/groups/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updatePopScreenGroup(
            @PathVariable Integer id,
            @RequestBody Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        body.put("id",          id);
        body.put("company_code", companyCode);
        body.put("user_id",      userId);
        try {
            return ResponseEntity.ok(ApiResponse.success(service.updatePopScreenGroup(body)));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "그룹을 찾을 수 없습니다"));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "POP 화면 그룹 수정 중 오류가 발생했습니다"));
        } catch (Exception e) {
            log.error("POP 화면 그룹 수정 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("POP 화면 그룹 수정 중 오류가 발생했습니다"));
        }
    }

    /** DELETE /api/screen-groups/pop/groups/:id */
    @DeleteMapping("/pop/groups/{id}")
    public ResponseEntity<ApiResponse<Void>> deletePopScreenGroup(
            @PathVariable Integer id,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",          id);
        params.put("company_code", companyCode);
        params.put("user_id",      userId);
        try {
            service.deletePopScreenGroup(params);
            return ResponseEntity.ok(ApiResponse.success(null, "POP 화면 그룹이 삭제되었습니다"));
        } catch (NoSuchElementException e) {
            return ResponseEntity.status(404).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "그룹을 찾을 수 없습니다"));
        } catch (SecurityException e) {
            return ResponseEntity.status(403).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "권한이 없습니다"));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(400).body(ApiResponse.error(
                    e.getMessage() != null ? e.getMessage() : "POP 화면 그룹 삭제 중 오류가 발생했습니다"));
        } catch (Exception e) {
            log.error("POP 화면 그룹 삭제 실패: id={}", id, e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("POP 화면 그룹 삭제 중 오류가 발생했습니다"));
        }
    }

    /** POST /api/screen-groups/pop/ensure-root */
    @PostMapping("/pop/ensure-root")
    public ResponseEntity<ApiResponse<Map<String, Object>>> ensurePopRootGroup(
            @RequestBody(required = false) Map<String, Object> body,
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("company_code", companyCode);
            params.put("user_id",      userId);
            if (body != null) params.putAll(body);
            Map<String, Object> result = service.ensurePopRootGroup(params);
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            log.error("POP 루트 그룹 확보 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("POP 루트 그룹 확보 중 오류가 발생했습니다"));
        }
    }
}
