package com.erp.controller;

import com.erp.dto.ApiResponse;
import com.erp.provisioning.SuperAdminGuard;
import com.erp.service.AdminService;
import jakarta.servlet.http.HttpServletRequest;
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.List;
import java.util.Map;

@RestController
@RequestMapping("/api/admin")
@RequiredArgsConstructor
@Slf4j
public class AdminController {

    private final AdminService adminService;

    // ── 메뉴 관리 ──────────────────────────────────────────────────────────

    /**
     * GET /api/admin/menus
     * 관리자 메뉴 목록 조회
     */
    @GetMapping("/menus")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getAdminMenus(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("role") String role,
            @RequestAttribute("user_id") String userId,
            @RequestParam Map<String, Object> params,
            HttpServletRequest request) {
        params.put("company_code", companyCode);
        params.put("user_type", role);
        params.put("user_id", userId);
        params.putIfAbsent("user_lang", "ko");
        params.put("is_management_screen",
                params.get("menu_type") == null || "true".equals(params.get("include_inactive")));
        // 관리 호스트(solution.invyone.com 등) 여부 — 테넌트 호스트이면 IS_SOLUTION_ONLY 메뉴를 SQL 단계에서 제외
        String host = request.getHeader("Host");
        params.put("is_management_host", !SuperAdminGuard.isTenantHost(host));
        return ResponseEntity.ok(ApiResponse.success(adminService.getAdminMenuList(params), "관리자 메뉴 목록 조회 성공"));
    }

    /**
     * GET /api/admin/user-menus
     * 사용자 메뉴 목록 조회 (사이드바)
     */
    @GetMapping("/user-menus")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getUserMenus(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("role") String role,
            @RequestAttribute("user_id") String userId,
            @RequestParam Map<String, Object> params,
            HttpServletRequest request) {
        params.put("company_code", companyCode);
        params.put("user_type", role);
        params.put("user_id", userId);
        params.putIfAbsent("user_lang", "ko");
        // 관리 호스트(solution.invyone.com 등) 여부 — 테넌트 호스트이면 IS_SOLUTION_ONLY 메뉴를 SQL 단계에서 제외
        String host = request.getHeader("Host");
        params.put("is_management_host", !SuperAdminGuard.isTenantHost(host));
        return ResponseEntity.ok(ApiResponse.success(adminService.getUserMenuList(params), "사용자 메뉴 목록 조회 성공"));
    }

    /**
     * GET /api/admin/pop-menus
     * POP 메뉴 목록 조회
     */
    @GetMapping("/pop-menus")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getPopMenus(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("role") String role) {
        Map<String, Object> params = new HashMap<>();
        params.put("company_code", companyCode);
        params.put("user_type", role);
        return ResponseEntity.ok(ApiResponse.success(adminService.getPopMenuList(params), "POP 메뉴 목록 조회 성공"));
    }

    /**
     * GET /api/admin/menus/{menuId}
     * 메뉴 단건 조회
     */
    @GetMapping("/menus/{menuId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getMenuInfo(@PathVariable String menuId) {
        Map<String, Object> menu = adminService.getMenuInfo(menuId);
        if (menu == null) {
            return ResponseEntity.status(404).body(ApiResponse.error("메뉴를 찾을 수 없습니다."));
        }
        return ResponseEntity.ok(ApiResponse.success(menu, "메뉴 정보 조회 성공"));
    }

    /**
     * POST /api/admin/menus
     * 메뉴 등록
     */
    @PostMapping("/menus")
    public ResponseEntity<ApiResponse<Map<String, Object>>> saveMenu(
            @RequestAttribute("company_code") String companyCode,
            @RequestBody Map<String, Object> body) {
        body.put("company_code", companyCode);
        return ResponseEntity.ok(ApiResponse.success(adminService.saveMenu(body), "메뉴 등록 성공"));
    }

    /**
     * PUT /api/admin/menus/{menuId}
     * 메뉴 수정
     */
    @PutMapping("/menus/{menuId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateMenu(
            @PathVariable String menuId,
            @RequestBody Map<String, Object> body) {
        return ResponseEntity.ok(ApiResponse.success(adminService.updateMenu(menuId, body), "메뉴 수정 성공"));
    }

    /**
     * DELETE /api/admin/menus/{menuId}
     * 메뉴 삭제
     */
    @DeleteMapping("/menus/{menuId}")
    public ResponseEntity<ApiResponse<Void>> deleteMenu(@PathVariable String menuId) {
        adminService.deleteMenu(menuId);
        return ResponseEntity.ok(ApiResponse.success(null, "메뉴 삭제 성공"));
    }

    /**
     * PUT /api/admin/menus/{menuId}/toggle
     * 메뉴 상태 토글
     */
    @PutMapping("/menus/{menuId}/toggle")
    public ResponseEntity<ApiResponse<Map<String, Object>>> toggleMenuStatus(@PathVariable String menuId) {
        return ResponseEntity.ok(ApiResponse.success(adminService.toggleMenuStatus(menuId), "메뉴 상태 변경 성공"));
    }

    /**
     * DELETE /api/admin/menus/batch
     * 메뉴 일괄 삭제
     */
    @DeleteMapping("/menus/batch")
    public ResponseEntity<ApiResponse<Map<String, Object>>> deleteMenusBatch(@RequestBody List<String> menuIds) {
        int deletedCount = 0;
        int failedCount = 0;
        if (menuIds != null) {
            for (String menuId : menuIds) {
                try {
                    adminService.deleteMenu(menuId);
                    deletedCount++;
                } catch (Exception e) {
                    failedCount++;
                    log.warn("메뉴 삭제 실패 menuId={} : {}", menuId, e.getMessage());
                }
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("deletedCount", deletedCount);
        result.put("failedCount", failedCount);
        return ResponseEntity.ok(ApiResponse.success(result, "메뉴 일괄 삭제 성공"));
    }

    // ── 사용자 관리 ────────────────────────────────────────────────────────

    /**
     * GET /api/admin/users
     * 사용자 목록 조회
     */
    @GetMapping("/users")
    public ResponseEntity<?> getUserList(
            @RequestAttribute("company_code") String companyCode,
            @RequestAttribute("role") String role,
            @RequestParam Map<String, Object> params) {
        // SUPER_ADMIN이 아닌 경우 자사 필터 적용
        if (!"SUPER_ADMIN".equals(role)) {
            params.put("company_code", companyCode);
        } else {
            params.put("company_code", "*");
        }
        params.putIfAbsent("page", "1");
        params.putIfAbsent("limit", "20");

        Map<String, Object> result = adminService.getUserList(params);

        // Node.js 응답 형식: success, data, total, searchType, pagination, message
        Map<String, Object> response = new HashMap<>(result);
        response.put("success", true);
        response.put("message", "사용자 목록 조회 성공");
        return ResponseEntity.ok(response);
    }

    /**
     * GET /api/admin/users/{userId}
     * 사용자 단건 조회
     */
    @GetMapping("/users/{userId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getUserInfo(@PathVariable String userId) {
        Map<String, Object> user = adminService.getUserInfo(userId);
        if (user == null) {
            return ResponseEntity.status(404).body(ApiResponse.error("사용자를 찾을 수 없습니다."));
        }
        return ResponseEntity.ok(ApiResponse.success(user, "사용자 정보 조회 성공"));
    }

    /**
     * GET /api/admin/users/{userId}/history
     * 사용자 변경이력 조회
     */
    @GetMapping("/users/{userId}/history")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getUserHistory(
            @PathVariable String userId,
            @RequestParam Map<String, Object> params) {
        return ResponseEntity.ok(ApiResponse.success(adminService.getUserHistory(userId, params), "사용자 변경이력 조회 성공"));
    }

    /**
     * GET /api/admin/users/{userId}/with-dept
     * 사원 + 부서 정보 조회 (수정 모달용)
     */
    @GetMapping("/users/{userId}/with-dept")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getUserWithDept(
            @RequestAttribute("company_code") String companyCode,
            @PathVariable String userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("company_code", companyCode);
        params.put("user_id", userId);
        Map<String, Object> result = adminService.getUserWithDept(params);
        if (result == null) {
            return ResponseEntity.status(404).body(ApiResponse.error("사용자를 찾을 수 없습니다."));
        }
        return ResponseEntity.ok(ApiResponse.success(result));
    }

    /**
     * POST /api/admin/users/with-dept
     * 사원 + 부서 통합 저장
     */
    @PostMapping("/users/with-dept")
    public ResponseEntity<ApiResponse<Map<String, Object>>> saveUserWithDept(
            @RequestAttribute("company_code") String companyCode,
            @RequestBody Map<String, Object> body) {
        body.put("company_code", companyCode);
        return ResponseEntity.ok(ApiResponse.success(adminService.saveUserWithDept(body)));
    }

    /**
     * POST /api/admin/users
     * 사용자 등록/수정
     */
    @PostMapping("/users")
    public ResponseEntity<ApiResponse<Map<String, Object>>> saveUser(
            @RequestAttribute("company_code") String companyCode,
            @RequestBody Map<String, Object> body) {
        body.put("company_code", companyCode);
        return ResponseEntity.ok(ApiResponse.success(adminService.saveUser(body), "사용자 저장 성공"));
    }

    /**
     * PUT /api/admin/users/{userId}
     * 사용자 수정 (REST)
     */
    @PutMapping("/users/{userId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateUser(
            @PathVariable String userId,
            @RequestAttribute("company_code") String companyCode,
            @RequestBody Map<String, Object> body) {
        body.put("user_id", userId);
        body.put("company_code", companyCode);
        return ResponseEntity.ok(ApiResponse.success(adminService.saveUser(body), "사용자 수정 성공"));
    }

    /**
     * DELETE /api/admin/users/{userId}
     * 사용자 삭제 (비활성화)
     */
    @DeleteMapping("/users/{userId}")
    public ResponseEntity<ApiResponse<Void>> deleteUser(
            @PathVariable String userId) {
        Map<String, Object> existing = adminService.getUserInfo(userId);
        if (existing == null) {
            return ResponseEntity.status(404).body(ApiResponse.error("사용자를 찾을 수 없습니다."));
        }
        adminService.changeUserStatus(userId, "inactive");
        return ResponseEntity.ok(ApiResponse.success(null, "사용자 삭제 성공"));
    }

    /**
     * PATCH /api/admin/users/{userId}/status
     * 사용자 상태 변경
     */
    @PatchMapping("/users/{userId}/status")
    public ResponseEntity<ApiResponse<Void>> changeUserStatus(
            @PathVariable String userId,
            @RequestBody Map<String, Object> body) {
        String status = (String) body.get("status");
        adminService.changeUserStatus(userId, status);
        return ResponseEntity.ok(ApiResponse.success(null, "사용자 상태 변경 성공"));
    }

    /**
     * POST /api/admin/users/reset-password
     * 비밀번호 초기화
     */
    @PostMapping("/users/reset-password")
    public ResponseEntity<ApiResponse<Void>> resetUserPassword(@RequestBody Map<String, Object> body) {
        String userId = (String) body.get("user_id");
        String newPassword = (String) body.get("new_password");
        adminService.resetUserPassword(userId, newPassword);
        return ResponseEntity.ok(ApiResponse.success(null, "비밀번호 초기화 성공"));
    }

    /**
     * POST /api/admin/users/check-duplicate
     * 사용자 ID 중복 확인
     */
    @PostMapping("/users/check-duplicate")
    public ResponseEntity<ApiResponse<Map<String, Object>>> checkDuplicateUserId(
            @RequestBody Map<String, Object> body) {
        String userId = (String) body.get("user_id");
        Map<String, Object> existing = adminService.getUserInfo(userId);
        Map<String, Object> result = new HashMap<>();
        result.put("is_duplicate", existing != null);
        return ResponseEntity.ok(ApiResponse.success(result, "아이디 중복 확인 완료"));
    }

    // ── 프로필 수정 ────────────────────────────────────────────────────────

    /**
     * PUT /api/admin/profile
     * 프로필 수정 (본인)
     */
    @PutMapping("/profile")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateProfile(
            @RequestAttribute("user_id") String userId,
            @RequestBody Map<String, Object> body) {
        body.put("user_id", userId);
        return ResponseEntity.ok(ApiResponse.success(adminService.saveUser(body), "프로필 수정 성공"));
    }

    // ── 부서 관리 ──────────────────────────────────────────────────────────

    /**
     * GET /api/admin/departments
     * 부서 목록 조회
     */
    @GetMapping("/departments")
    public ResponseEntity<?> getDepartmentList(
            @RequestAttribute("company_code") String companyCode,
            @RequestParam Map<String, Object> params) {
        params.put("company_code", companyCode);
        Map<String, Object> serviceResult = adminService.getDepartmentList(params);

        int total = ((Number) serviceResult.get("total")).intValue();

        Map<String, Object> data = new HashMap<>();
        data.put("departments", serviceResult.get("departments"));
        data.put("flat_list", serviceResult.get("flat_list"));

        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("data", data);
        response.put("message", "부서 목록 조회 성공");
        response.put("total", total);
        response.put("total_count", total);
        return ResponseEntity.ok(response);
    }

    // ── 회사 관리 ──────────────────────────────────────────────────────────

    /**
     * GET /api/admin/companies
     * 회사 목록 조회
     */
    @GetMapping("/companies")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getCompanyList() {
        return ResponseEntity.ok(ApiResponse.success(adminService.getCompanyList(), "회사 목록 조회 성공"));
    }

    /**
     * GET /api/admin/companies/db
     * 실제 DB에서 회사 목록 조회
     */
    @GetMapping("/companies/db")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getCompanyListFromDB() {
        return ResponseEntity.ok(ApiResponse.success(adminService.getCompanyList(), "회사 목록 조회 성공"));
    }

    /**
     * GET /api/admin/companies/{companyCode}
     * 회사 단건 조회
     */
    @GetMapping("/companies/{companyCode}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getCompanyByCode(
            @PathVariable String companyCode) {
        Map<String, Object> company = adminService.getCompanyByCode(companyCode);
        if (company == null) {
            return ResponseEntity.status(404).body(ApiResponse.error("회사를 찾을 수 없습니다."));
        }
        return ResponseEntity.ok(ApiResponse.success(company, "회사 조회 성공"));
    }

    /**
     * POST /api/admin/companies
     * 회사 등록
     */
    @PostMapping("/companies")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createCompany(
            @RequestBody Map<String, Object> body) {
        return ResponseEntity.ok(ApiResponse.success(adminService.createCompany(body), "회사 등록 성공"));
    }

    /**
     * PUT /api/admin/companies/{companyCode}
     * 회사 수정
     */
    @PutMapping("/companies/{companyCode}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateCompany(
            @PathVariable String companyCode,
            @RequestBody Map<String, Object> body) {
        return ResponseEntity.ok(ApiResponse.success(adminService.updateCompanyInfo(companyCode, body), "회사 수정 성공"));
    }

    /**
     * DELETE /api/admin/companies/{companyCode}
     * 회사 삭제 (비활성화)
     */
    @DeleteMapping("/companies/{companyCode}")
    public ResponseEntity<ApiResponse<Void>> deleteCompany(@PathVariable String companyCode) {
        adminService.deleteCompany(companyCode);
        return ResponseEntity.ok(ApiResponse.success(null, "회사 삭제 성공"));
    }

    // ── 로케일 관리 ────────────────────────────────────────────────────────

    /**
     * GET /api/admin/user-locale
     * 사용자 로케일 조회
     */
    @GetMapping("/user-locale")
    public ResponseEntity<ApiResponse<Object>> getUserLocale(
            @RequestAttribute("user_id") String userId) {
        Map<String, Object> row = adminService.getUserLocale(userId);
        Object locale = row.getOrDefault("locale", "KR");
        return ResponseEntity.ok(ApiResponse.success(locale, "사용자 로케일 조회 성공"));
    }

    /**
     * POST /api/admin/user-locale
     * 사용자 로케일 설정
     */
    @PostMapping("/user-locale")
    public ResponseEntity<ApiResponse<Object>> setUserLocale(
            @RequestAttribute("user_id") String userId,
            @RequestBody Map<String, Object> body) {
        String locale = (String) body.get("locale");
        if (locale == null || locale.isBlank()) {
            return ResponseEntity.badRequest().body(ApiResponse.error("로케일이 필요합니다."));
        }
        try {
            adminService.setUserLocale(userId, locale);
            return ResponseEntity.ok(ApiResponse.success(locale, "사용자 로케일 설정 성공"));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage()));
        }
    }

    // ── 테이블 스키마 ──────────────────────────────────────────────────────

    /**
     * GET /api/admin/tables/{tableName}/schema
     * 테이블 스키마 조회
     */
    @GetMapping("/tables/{tableName}/schema")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getTableSchema(
            @PathVariable String tableName) {
        return ResponseEntity.ok(ApiResponse.success(adminService.getTableSchema(tableName), "테이블 스키마 조회 성공"));
    }
}
