package com.erp.controller;

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

import java.util.*;

@Slf4j
@RestController
@RequestMapping("/api/multilang")
@RequiredArgsConstructor
public class MultilangController {

    private final MultilangService multilangService;

    // ─────────────────────────────────────────────────────────────────────────
    // 배치 번역 (인증 불필요 — SecurityConfig에서 permitAll)
    // ─────────────────────────────────────────────────────────────────────────

    @PostMapping("/batch")
    public ResponseEntity<ApiResponse<Map<String, String>>> getBatchTranslations(
            @RequestBody Map<String, Object> body,
            @RequestParam(required = false) String companyCode,
            @RequestParam(required = false) String menuCode,
            @RequestParam(required = false) String userLang) {

        String finalCompanyCode = companyCode != null ? companyCode : str(body.get("company_code"));
        String finalMenuCode = menuCode != null ? menuCode : str(body.get("menu_code"));
        String finalUserLang = userLang != null ? userLang : str(body.get("user_lang"));

        @SuppressWarnings("unchecked")
        List<String> langKeys = (List<String>) body.get("lang_keys");

        if (langKeys == null || langKeys.isEmpty()) {
            return ResponseEntity.badRequest().body(ApiResponse.error("langKeys 배열이 필요합니다."));
        }
        if (finalCompanyCode.isEmpty() || finalUserLang.isEmpty()) {
            return ResponseEntity.badRequest().body(ApiResponse.error("companyCode와 userLang은 필수입니다."));
        }

        Map<String, String> translations =
                multilangService.getBatchTranslations(finalCompanyCode, finalMenuCode, finalUserLang, langKeys);
        return ResponseEntity.ok(ApiResponse.success(translations, "다국어 텍스트 배치 조회 성공"));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 언어 관리
    // ─────────────────────────────────────────────────────────────────────────

    @GetMapping("/languages")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getLanguages() {
        return ResponseEntity.ok(ApiResponse.success(
                multilangService.getLanguages(), "언어 목록 조회 성공"));
    }

    @PostMapping("/languages")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createLanguage(
            @RequestAttribute("company_code") String companyCode,
            @RequestBody Map<String, Object> body) {

        String langCode = str(body.get("lang_code"));
        String langName = str(body.get("lang_name"));
        String langNative = str(body.get("lang_native"));

        if (langCode.isEmpty() || langName.isEmpty() || langNative.isEmpty()) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("언어 코드, 언어명, 원어명은 필수입니다."));
        }

        String userId = str(body.getOrDefault("created_by", "system"));
        body.put("created_by", userId);
        body.put("updated_by", userId);
        Map<String, Object> created = multilangService.createLanguage(body);
        return ResponseEntity.status(201)
                .body(ApiResponse.success(created, "언어가 성공적으로 생성되었습니다."));
    }

    @PutMapping("/languages/{langCode}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateLanguage(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable String langCode,
            @RequestBody Map<String, Object> body) {

        String userId = str(body.getOrDefault("updated_by", "system"));
        body.put("updated_by", userId);
        Map<String, Object> updated = multilangService.updateLanguage(langCode, body);
        return ResponseEntity.ok(ApiResponse.success(updated, "언어가 성공적으로 수정되었습니다."));
    }

    @DeleteMapping("/languages/{langCode}")
    public ResponseEntity<ApiResponse<String>> deleteLanguage(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable String langCode) {

        multilangService.deleteLanguage(langCode);
        return ResponseEntity.ok(ApiResponse.success("삭제 완료", "언어가 성공적으로 삭제되었습니다."));
    }

    @PutMapping("/languages/{langCode}/toggle")
    public ResponseEntity<ApiResponse<String>> toggleLanguage(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable String langCode) {

        String result = multilangService.toggleLanguage(langCode);
        return ResponseEntity.ok(ApiResponse.success(result, "언어가 " + result + "되었습니다."));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 다국어 키 관리
    // ─────────────────────────────────────────────────────────────────────────

    @GetMapping("/keys")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getLangKeys(
            @RequestAttribute("company_code") String companyCode,
            @RequestParam Map<String, Object> params) {

        List<Map<String, Object>> keys = multilangService.getLangKeys(new HashMap<>(params));
        return ResponseEntity.ok(ApiResponse.success(keys, "다국어 키 목록 조회 성공"));
    }

    @GetMapping("/keys/{keyId}/texts")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getLangTexts(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int keyId) {

        return ResponseEntity.ok(ApiResponse.success(
                multilangService.getLangTexts(keyId), "다국어 텍스트 조회 성공"));
    }

    @PostMapping("/keys")
    public ResponseEntity<ApiResponse<Integer>> createLangKey(
            @RequestAttribute("company_code") String companyCode,
            @RequestBody Map<String, Object> body) {

        if (str(body.get("company_code")).isEmpty() || str(body.get("lang_key")).isEmpty()) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("회사 코드와 언어 키는 필수입니다."));
        }

        String userId = str(body.getOrDefault("created_by", "system"));
        body.put("created_by", userId);
        body.put("updated_by", userId);
        int keyId = multilangService.createLangKey(body);
        return ResponseEntity.status(201)
                .body(ApiResponse.success(keyId, "다국어 키가 성공적으로 생성되었습니다."));
    }

    @PutMapping("/keys/{keyId}")
    public ResponseEntity<ApiResponse<String>> updateLangKey(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int keyId,
            @RequestBody Map<String, Object> body) {

        String userId = str(body.getOrDefault("updated_by", "system"));
        body.put("updated_by", userId);
        multilangService.updateLangKey(keyId, body);
        return ResponseEntity.ok(ApiResponse.success("수정 완료", "다국어 키가 성공적으로 수정되었습니다."));
    }

    @DeleteMapping("/keys/{keyId}")
    public ResponseEntity<ApiResponse<String>> deleteLangKey(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int keyId) {

        multilangService.deleteLangKey(keyId);
        return ResponseEntity.ok(ApiResponse.success("삭제 완료", "다국어 키가 성공적으로 삭제되었습니다."));
    }

    @PutMapping("/keys/{keyId}/toggle")
    public ResponseEntity<ApiResponse<String>> toggleLangKey(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int keyId) {

        String result = multilangService.toggleLangKey(keyId);
        return ResponseEntity.ok(ApiResponse.success(result, "다국어 키가 " + result + "되었습니다."));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 다국어 텍스트 관리
    // ─────────────────────────────────────────────────────────────────────────

    @PostMapping("/keys/{keyId}/texts")
    public ResponseEntity<ApiResponse<String>> saveLangTexts(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int keyId,
            @RequestBody Map<String, Object> body) {

        @SuppressWarnings("unchecked")
        List<Map<String, Object>> texts = (List<Map<String, Object>>) body.get("texts");
        if (texts == null || texts.isEmpty()) {
            return ResponseEntity.badRequest().body(ApiResponse.error("텍스트 데이터는 필수입니다."));
        }

        String userId = str(body.getOrDefault("updated_by", "system"));
        for (Map<String, Object> t : texts) {
            if (t.get("created_by") == null) t.put("created_by", userId);
            if (t.get("updated_by") == null) t.put("updated_by", userId);
        }
        multilangService.saveLangTexts(keyId, texts);
        return ResponseEntity.ok(ApiResponse.success("저장 완료", "다국어 텍스트가 성공적으로 저장되었습니다."));
    }

    @GetMapping("/user-text/{companyCode}/{menuCode}/{langKey}")
    public ResponseEntity<ApiResponse<String>> getUserText(
            @PathVariable String companyCode,
            @PathVariable String menuCode,
            @PathVariable String langKey,
            @RequestParam(required = false) String userLang) {

        if (userLang == null || userLang.isEmpty()) {
            return ResponseEntity.badRequest().body(ApiResponse.error("사용자 언어는 필수입니다."));
        }
        String text = multilangService.getUserText(companyCode, menuCode, langKey, userLang);
        return ResponseEntity.ok(ApiResponse.success(text, "사용자별 다국어 텍스트 조회 성공"));
    }

    @GetMapping("/text/{companyCode}/{langKey}/{langCode}")
    public ResponseEntity<ApiResponse<String>> getLangText(
            @PathVariable String companyCode,
            @PathVariable String langKey,
            @PathVariable String langCode) {

        String text = multilangService.getLangText(companyCode, langKey, langCode);
        return ResponseEntity.ok(ApiResponse.success(text, "특정 키의 다국어 텍스트 조회 성공"));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 카테고리 관리
    // ─────────────────────────────────────────────────────────────────────────

    @GetMapping("/categories")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getCategories(
            @RequestAttribute("company_code") String companyCode) {

        return ResponseEntity.ok(ApiResponse.success(
                multilangService.getCategories(), "카테고리 목록 조회 성공"));
    }

    @GetMapping("/categories/{categoryId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getCategoryById(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int categoryId) {

        Map<String, Object> category = multilangService.getCategoryById(categoryId);
        if (category == null) {
            return ResponseEntity.status(404).body(ApiResponse.error("카테고리를 찾을 수 없습니다."));
        }
        return ResponseEntity.ok(ApiResponse.success(category, "카테고리 상세 조회 성공"));
    }

    @GetMapping("/categories/{categoryId}/path")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getCategoryPath(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable int categoryId) {

        return ResponseEntity.ok(ApiResponse.success(
                multilangService.getCategoryPath(categoryId), "카테고리 경로 조회 성공"));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 자동 생성 및 오버라이드
    // ─────────────────────────────────────────────────────────────────────────

    @PostMapping("/keys/generate")
    public ResponseEntity<ApiResponse<Integer>> generateKey(
            @RequestAttribute("company_code") String requestCompanyCode,
            @RequestBody Map<String, Object> body) {

        String targetCompanyCode = str(body.get("company_code"));
        if (targetCompanyCode.isEmpty() || str(body.get("category_id")).isEmpty()
                || str(body.get("key_meaning")).isEmpty()) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("회사 코드, 카테고리 ID, 키 의미는 필수입니다."));
        }
        if ("*".equals(targetCompanyCode) && !"*".equals(requestCompanyCode)) {
            return ResponseEntity.status(403)
                    .body(ApiResponse.error("공통 키는 최고 관리자만 생성할 수 있습니다."));
        }
        if (!"*".equals(targetCompanyCode) && !"*".equals(requestCompanyCode)
                && !targetCompanyCode.equals(requestCompanyCode)) {
            return ResponseEntity.status(403)
                    .body(ApiResponse.error("다른 회사의 키를 생성할 권한이 없습니다."));
        }

        body.put("created_by", body.getOrDefault("created_by", "system"));
        int keyId = multilangService.generateKey(body);
        return ResponseEntity.status(201)
                .body(ApiResponse.success(keyId, "키가 성공적으로 생성되었습니다."));
    }

    @PostMapping("/keys/preview")
    public ResponseEntity<ApiResponse<Map<String, Object>>> previewKey(
            @RequestAttribute("company_code") String companyCode,
            @RequestBody Map<String, Object> body) {

        Object categoryIdObj = body.get("category_id");
        String keyMeaning = str(body.get("key_meaning"));
        String targetCompanyCode = str(body.get("company_code"));

        if (categoryIdObj == null || keyMeaning.isEmpty() || targetCompanyCode.isEmpty()) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("카테고리 ID, 키 의미, 회사 코드는 필수입니다."));
        }

        int categoryId = toInt(categoryIdObj);
        Map<String, Object> preview = multilangService.previewKey(categoryId, keyMeaning, targetCompanyCode);
        return ResponseEntity.ok(ApiResponse.success(preview, "키 미리보기 성공"));
    }

    @PostMapping("/keys/override")
    public ResponseEntity<ApiResponse<Integer>> createOverrideKey(
            @RequestAttribute("company_code") String requestCompanyCode,
            @RequestBody Map<String, Object> body) {

        String targetCompanyCode = str(body.get("company_code"));
        if (targetCompanyCode.isEmpty() || body.get("base_key_id") == null) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("회사 코드와 원본 키 ID는 필수입니다."));
        }
        if ("*".equals(targetCompanyCode)) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("공통 키에 대한 오버라이드는 생성할 수 없습니다."));
        }
        if (!"*".equals(requestCompanyCode) && !targetCompanyCode.equals(requestCompanyCode)) {
            return ResponseEntity.status(403)
                    .body(ApiResponse.error("다른 회사의 오버라이드 키를 생성할 권한이 없습니다."));
        }

        body.put("created_by", body.getOrDefault("created_by", "system"));
        int keyId = multilangService.createOverrideKey(body);
        return ResponseEntity.status(201)
                .body(ApiResponse.success(keyId, "오버라이드 키가 성공적으로 생성되었습니다."));
    }

    @GetMapping("/keys/overrides/{companyCode}")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getOverrideKeys(
            @RequestAttribute("company_code") String requestCompanyCode,
            @PathVariable String companyCode) {

        if (!"*".equals(requestCompanyCode) && !companyCode.equals(requestCompanyCode)) {
            return ResponseEntity.status(403)
                    .body(ApiResponse.error("다른 회사의 오버라이드 키를 조회할 권한이 없습니다."));
        }
        return ResponseEntity.ok(ApiResponse.success(
                multilangService.getOverrideKeys(companyCode), "오버라이드 키 목록 조회 성공"));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // 화면 라벨 다국어 자동 생성
    // ─────────────────────────────────────────────────────────────────────────

    @PostMapping("/screen-labels")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> generateScreenLabelKeys(
            @RequestAttribute("company_code") String requestCompanyCode,
            @RequestBody Map<String, Object> body) {

        Object screenIdObj = body.get("screen_id");
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> labels = (List<Map<String, Object>>) body.get("labels");

        if (screenIdObj == null) {
            return ResponseEntity.badRequest().body(ApiResponse.error("screenId는 필수입니다."));
        }
        if (labels == null || labels.isEmpty()) {
            return ResponseEntity.badRequest().body(ApiResponse.error("labels 배열이 필요합니다."));
        }

        // companyCode, companyName이 body에 없으면 requestCompanyCode 사용
        if (!body.containsKey("company_code") || str(body.get("company_code")).isEmpty()) {
            body.put("company_code", requestCompanyCode);
        }
        if (!body.containsKey("company_name") || str(body.get("company_name")).isEmpty()) {
            body.put("company_name", requestCompanyCode);
        }

        body.put("screen_id", toInt(screenIdObj));
        List<Map<String, Object>> results = multilangService.generateScreenLabelKeys(body);
        return ResponseEntity.ok(ApiResponse.success(
                results, results.size() + "개의 다국어 키가 생성되었습니다."));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Private utilities
    // ─────────────────────────────────────────────────────────────────────────

    private String str(Object o) {
        return o == null ? "" : o.toString();
    }

    private int toInt(Object o) {
        if (o == null) return 0;
        if (o instanceof Number) return ((Number) o).intValue();
        try { return Integer.parseInt(o.toString()); } catch (NumberFormatException e) { return 0; }
    }
}
