package com.erp.controller;

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

import java.util.Map;

@RestController
@RequestMapping("/api/layouts")
@RequiredArgsConstructor
@Slf4j
public class LayoutController {

    private final LayoutService layoutService;

    /**
     * GET /api/layouts
     * 레이아웃 목록 조회
     * @param params page, size, category, layoutType, searchTerm, includePublic
     */
    @GetMapping
    public ResponseEntity<ApiResponse<Map<String, Object>>> getLayouts(
            @RequestAttribute("company_code") String companyCode,
            @RequestParam Map<String, Object> params) {
        params.put("company_code", companyCode);
        return ResponseEntity.ok(ApiResponse.success(layoutService.getLayouts(params)));
    }

    /**
     * GET /api/layouts/counts-by-category
     * 카테고리별 레이아웃 개수 조회
     * ※ /{id} 보다 먼저 선언해야 Spring MVC 가 정확히 매핑함
     */
    @GetMapping("/counts-by-category")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getLayoutCountsByCategory(
            @RequestAttribute("company_code") String companyCode) {
        return ResponseEntity.ok(ApiResponse.success(
                layoutService.getLayoutCountsByCategory(companyCode)));
    }

    /**
     * GET /api/layouts/:id
     * 레이아웃 상세 조회
     */
    @GetMapping("/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getLayoutById(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable("id") String layoutCode) {
        Map<String, Object> layout = layoutService.getLayoutById(layoutCode, companyCode);
        if (layout == null) {
            return ResponseEntity.status(404)
                    .body(ApiResponse.error("레이아웃을 찾을 수 없습니다."));
        }
        return ResponseEntity.ok(ApiResponse.success(layout));
    }

    /**
     * POST /api/layouts
     * 레이아웃 생성
     */
    @PostMapping
    public ResponseEntity<ApiResponse<Map<String, Object>>> createLayout(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @RequestBody Map<String, Object> body) {

        if (body.get("layout_name") == null || body.get("layout_type") == null || body.get("category") == null) {
            return ResponseEntity.status(400)
                    .body(ApiResponse.error("필수 필드가 누락되었습니다. (layoutName, layoutType, category)"));
        }
        if (body.get("layout_config") == null || body.get("zones_config") == null) {
            return ResponseEntity.status(400)
                    .body(ApiResponse.error("레이아웃 설정과 존 설정은 필수입니다."));
        }

        try {
            Map<String, Object> created = layoutService.createLayout(body, companyCode, userId);
            return ResponseEntity.status(201)
                    .body(ApiResponse.success(created, "레이아웃이 성공적으로 생성되었습니다."));
        } catch (Exception e) {
            log.error("레이아웃 생성 실패", e);
            return ResponseEntity.status(500)
                    .body(ApiResponse.error("레이아웃 생성에 실패했습니다."));
        }
    }

    /**
     * PUT /api/layouts/:id
     * 레이아웃 수정
     */
    @PutMapping("/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateLayout(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @PathVariable("id") String layoutCode,
            @RequestBody Map<String, Object> body) {

        try {
            Map<String, Object> updated = layoutService.updateLayout(layoutCode, 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/layouts/:id
     * 레이아웃 삭제 (소프트)
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteLayout(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @PathVariable("id") String layoutCode) {

        try {
            layoutService.deleteLayout(layoutCode, companyCode, userId);
            return ResponseEntity.ok(ApiResponse.success(null, "레이아웃이 성공적으로 삭제되었습니다."));
        } 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("레이아웃 삭제에 실패했습니다."));
        }
    }

    /**
     * POST /api/layouts/:id/duplicate
     * 레이아웃 복제
     */
    @PostMapping("/{id}/duplicate")
    public ResponseEntity<ApiResponse<Map<String, Object>>> duplicateLayout(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("user_id") String userId,
            @PathVariable("id") String layoutCode,
            @RequestBody Map<String, Object> body) {

        String newName = (String) body.get("new_name");
        if (newName == null || newName.isBlank()) {
            return ResponseEntity.status(400)
                    .body(ApiResponse.error("새 레이아웃 이름이 필요합니다."));
        }

        try {
            Map<String, Object> duplicated = layoutService.duplicateLayout(
                    layoutCode, newName, companyCode, userId);
            return ResponseEntity.status(201)
                    .body(ApiResponse.success(duplicated, "레이아웃이 성공적으로 복제되었습니다."));
        } 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("레이아웃 복제에 실패했습니다."));
        }
    }
}
