package kr.co.zioinfo.web.controller;

import kr.co.zioinfo.web.model.*;
import kr.co.zioinfo.web.repository.*;
import kr.co.zioinfo.web.security.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.*;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.stream.Collectors;

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

    private final AdminUserRepository adminUserRepo;
    private final NewsRepository newsRepo;
    private final InquiryRepository inquiryRepo;
    private final RecruitRepository recruitRepo;
    private final MemberRepository memberRepo;
    private final CompanyHistoryRepository historyRepo;
    private final FaqRepository faqRepo;
    private final JwtUtil jwtUtil;
    private final PasswordEncoder passwordEncoder;

    // ── 로그인 ────────────────────────────────────────────────
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody Map<String, String> body) {
        String username = body.get("username");
        String password = body.get("password");

        return adminUserRepo.findByUsername(username)
                .filter(u -> u.isEnabled() && passwordEncoder.matches(password, u.getPassword()))
                .map(u -> ResponseEntity.ok(Map.of(
                        "token", jwtUtil.generate(u.getUsername()),
                        "username", u.getUsername(),
                        "displayName", Optional.ofNullable(u.getDisplayName()).orElse(u.getUsername()))))
                .orElse(ResponseEntity.status(401).body(Map.of("message", "아이디 또는 비밀번호가 올바르지 않습니다.")));
    }

    // ── 대시보드 통계 ────────────────────────────────────────
    @GetMapping("/dashboard")
    public ResponseEntity<Map<String, Object>> dashboard() {
        Map<String, Object> stats = new LinkedHashMap<>();
        stats.put("totalNews", newsRepo.count());
        stats.put("visibleNews", newsRepo.countByVisibleTrue());
        stats.put("totalInquiries", inquiryRepo.count());
        stats.put("pendingInquiries", inquiryRepo.countByStatus("PENDING"));
        stats.put("totalRecruits", recruitRepo.count());
        stats.put("activeRecruits", recruitRepo.countByActiveTrue());
        stats.put("totalMembers", memberRepo.count());
        stats.put("activeMembers", memberRepo.countByActiveTrue());
        stats.put("recentInquiries", inquiryRepo.findTop5ByOrderByCreatedAtDesc());
        stats.put("recentNews", newsRepo.findTop5ByOrderByCreatedAtDesc());
        return ResponseEntity.ok(stats);
    }

    // ── 연혁 관리 (CRUD) ─────────────────────────────────────
    @GetMapping("/history")
    public ResponseEntity<List<CompanyHistory>> adminHistory() {
        return ResponseEntity.ok(historyRepo.findAllByOrderByYearDescSortOrderAsc());
    }

    @PostMapping("/history")
    public ResponseEntity<CompanyHistory> createHistory(@RequestBody CompanyHistory h) {
        h.setId(null);
        return ResponseEntity.ok(historyRepo.save(h));
    }

    @PutMapping("/history/{id}")
    public ResponseEntity<CompanyHistory> updateHistory(
            @PathVariable Long id, @RequestBody CompanyHistory body) {
        return historyRepo.findById(id).map(h -> {
            h.setYear(body.getYear());
            h.setContent(body.getContent());
            h.setSortOrder(body.getSortOrder());
            h.setVisible(body.isVisible());
            return ResponseEntity.ok(historyRepo.save(h));
        }).orElse(ResponseEntity.notFound().build());
    }

    @DeleteMapping("/history/{id}")
    public ResponseEntity<Void> deleteHistory(@PathVariable Long id) {
        historyRepo.deleteById(id);
        return ResponseEntity.noContent().build();
    }

    /** 연도별 그룹 조회 (프론트 미리보기용) */
    @GetMapping("/history/grouped")
    public ResponseEntity<List<Map<String, Object>>> adminHistoryGrouped() {
        List<CompanyHistory> rows = historyRepo.findAllByOrderByYearDescSortOrderAsc();
        Map<String, List<Map<String, Object>>> grouped = new LinkedHashMap<>();
        for (CompanyHistory h : rows) {
            grouped.computeIfAbsent(h.getYear(), k -> new ArrayList<>())
                   .add(Map.of("id", h.getId(), "content", h.getContent(),
                               "sortOrder", h.getSortOrder(), "visible", h.isVisible()));
        }
        List<Map<String, Object>> result = grouped.entrySet().stream()
            .map(e -> Map.of("year", (Object)e.getKey(), "items", e.getValue()))
            .collect(Collectors.toList());
        return ResponseEntity.ok(result);
    }

    // ── 뉴스 관리 ────────────────────────────────────────────
    @GetMapping("/news")
    public ResponseEntity<Page<News>> adminNews(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        return ResponseEntity.ok(newsRepo.findAll(
                PageRequest.of(page, size, Sort.by("createdAt").descending())));
    }

    @PostMapping("/news")
    public ResponseEntity<News> createNews(@RequestBody News news) {
        news.setId(null);
        news.setCreatedAt(null);
        return ResponseEntity.ok(newsRepo.save(news));
    }

    @PutMapping("/news/{id}")
    public ResponseEntity<?> updateNews(@PathVariable Long id, @RequestBody News body) {
        return newsRepo.findById(id).map(n -> {
            n.setTitle(body.getTitle());
            n.setCategory(body.getCategory());
            n.setContent(body.getContent());
            n.setSummary(body.getSummary());
            n.setThumbnailUrl(body.getThumbnailUrl());
            n.setVisible(body.isVisible());
            return ResponseEntity.ok(newsRepo.save(n));
        }).orElse(ResponseEntity.notFound().build());
    }

    @DeleteMapping("/news/{id}")
    public ResponseEntity<Void> deleteNews(@PathVariable Long id) {
        if (!newsRepo.existsById(id)) return ResponseEntity.notFound().build();
        newsRepo.deleteById(id);
        return ResponseEntity.noContent().build();
    }

    @PatchMapping("/news/{id}/visibility")
    public ResponseEntity<?> toggleVisibility(@PathVariable Long id) {
        return newsRepo.findById(id).map(n -> {
            n.setVisible(!n.isVisible());
            return ResponseEntity.ok(newsRepo.save(n));
        }).orElse(ResponseEntity.notFound().build());
    }

    // ── FAQ 관리 ─────────────────────────────────────────────
    @GetMapping("/faq")
    public ResponseEntity<?> adminFaqList() {
        return ResponseEntity.ok(faqRepo.findAllByOrderByCategoryAscOrderNumAsc());
    }

    @PostMapping("/faq")
    public ResponseEntity<?> createFaq(@RequestBody kr.co.zioinfo.web.model.Faq faq) {
        faq.setId(null); faq.setCreatedAt(null);
        return ResponseEntity.ok(faqRepo.save(faq));
    }

    @PutMapping("/faq/{id}")
    public ResponseEntity<?> updateFaq(@PathVariable Long id,
                                       @RequestBody kr.co.zioinfo.web.model.Faq body) {
        return faqRepo.findById(id).map(f -> {
            f.setCategory(body.getCategory());
            f.setQuestion(body.getQuestion());
            f.setAnswer(body.getAnswer());
            f.setOrderNum(body.getOrderNum());
            f.setVisible(body.isVisible());
            return ResponseEntity.ok(faqRepo.save(f));
        }).orElse(ResponseEntity.notFound().build());
    }

    @DeleteMapping("/faq/{id}")
    public ResponseEntity<Void> deleteFaq(@PathVariable Long id) {
        if (!faqRepo.existsById(id)) return ResponseEntity.notFound().build();
        faqRepo.deleteById(id);
        return ResponseEntity.noContent().build();
    }

    // ── 문의 관리 ────────────────────────────────────────────
    @GetMapping("/inquiries")
    public ResponseEntity<Page<Inquiry>> adminInquiries(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String status) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
        Page<Inquiry> result = (status != null && !status.isBlank())
                ? inquiryRepo.findByStatus(status, pageable)
                : inquiryRepo.findAll(pageable);
        return ResponseEntity.ok(result);
    }

    @GetMapping("/inquiries/{id}")
    public ResponseEntity<Inquiry> getInquiry(@PathVariable Long id) {
        return inquiryRepo.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @PatchMapping("/inquiries/{id}/status")
    public ResponseEntity<?> updateInquiryStatus(
            @PathVariable Long id, @RequestBody Map<String, String> body) {
        return inquiryRepo.findById(id).map(i -> {
            i.setStatus(body.getOrDefault("status", i.getStatus()));
            return ResponseEntity.ok(inquiryRepo.save(i));
        }).orElse(ResponseEntity.notFound().build());
    }

    // ── 채용공고 관리 ────────────────────────────────────────
    @GetMapping("/recruits")
    public ResponseEntity<Page<Recruit>> adminRecruits(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        return ResponseEntity.ok(recruitRepo.findAllByOrderByCreatedAtDesc(
                PageRequest.of(page, size)));
    }

    @PostMapping("/recruits")
    public ResponseEntity<Recruit> createRecruit(@RequestBody Recruit recruit) {
        recruit.setId(null);
        recruit.setCreatedAt(null);
        return ResponseEntity.ok(recruitRepo.save(recruit));
    }

    @PutMapping("/recruits/{id}")
    public ResponseEntity<?> updateRecruit(@PathVariable Long id, @RequestBody Recruit body) {
        return recruitRepo.findById(id).map(r -> {
            r.setTitle(body.getTitle());
            r.setDepartment(body.getDepartment());
            r.setJobType(body.getJobType());
            r.setDescription(body.getDescription());
            r.setRequirements(body.getRequirements());
            r.setPreferred(body.getPreferred());
            r.setDeadline(body.getDeadline());
            r.setHeadcount(body.getHeadcount());
            r.setActive(body.isActive());
            return ResponseEntity.ok(recruitRepo.save(r));
        }).orElse(ResponseEntity.notFound().build());
    }

    @DeleteMapping("/recruits/{id}")
    public ResponseEntity<Void> deleteRecruit(@PathVariable Long id) {
        if (!recruitRepo.existsById(id)) return ResponseEntity.notFound().build();
        recruitRepo.deleteById(id);
        return ResponseEntity.noContent().build();
    }

    // ── 회원 관리 ────────────────────────────────────────────
    @GetMapping("/members")
    public ResponseEntity<?> listMembers(
            @RequestParam(defaultValue = "0")  int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(required = false)    String keyword) {
        Pageable pg = PageRequest.of(page, size, Sort.by("createdAt").descending());
        return ResponseEntity.ok(memberRepo.search(keyword, pg));
    }

    @GetMapping("/members/{id}")
    public ResponseEntity<?> getMember(@PathVariable Long id) {
        return memberRepo.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @PatchMapping("/members/{id}/status")
    public ResponseEntity<?> toggleMemberStatus(@PathVariable Long id,
                                                @RequestBody Map<String, Boolean> body) {
        return memberRepo.findById(id).map(m -> {
            m.setActive(body.getOrDefault("active", !m.isActive()));
            memberRepo.save(m);
            return ResponseEntity.ok(Map.of("id", m.getId(), "active", m.isActive()));
        }).orElse(ResponseEntity.notFound().build());
    }

    @DeleteMapping("/members/{id}")
    public ResponseEntity<?> deleteMember(@PathVariable Long id) {
        if (!memberRepo.existsById(id)) return ResponseEntity.notFound().build();
        memberRepo.deleteById(id);
        return ResponseEntity.noContent().build();
    }

    // ── 대시보드 통계에 회원 수 추가 ─────────────────────────
    // (기존 dashboard 메서드에 totalMembers 추가는 별도 수정)

    // ── 비밀번호 변경 ────────────────────────────────────────
    @PutMapping("/password")
    public ResponseEntity<?> changePassword(
            @RequestBody Map<String, String> body,
            jakarta.servlet.http.HttpServletRequest req) {
        String authHeader = req.getHeader("Authorization");
        String username = jwtUtil.extractUsername(authHeader.substring(7));
        return adminUserRepo.findByUsername(username).map(u -> {
            if (!passwordEncoder.matches(body.get("currentPassword"), u.getPassword()))
                return ResponseEntity.badRequest().body(Map.of("message", "현재 비밀번호가 올바르지 않습니다."));
            u.setPassword(passwordEncoder.encode(body.get("newPassword")));
            adminUserRepo.save(u);
            return ResponseEntity.ok(Map.of("message", "비밀번호가 변경되었습니다."));
        }).orElse(ResponseEntity.notFound().build());
    }
}
