package org.dromara.art.controller;

import java.util.List;
import java.util.Map;

import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.art.domain.vo.ArtSchoolDetailVo;
import org.dromara.art.domain.bo.ArtSchoolDetailBo;
import org.dromara.art.domain.ArtSchoolDetail;
import org.dromara.art.service.IArtSchoolDetailService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.json.utils.JsonUtils;

/**
 * 学校详细信息
 *
 * @author ZhouWenTao
 * @date 2026-02-17
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/art/schoolDetail")
public class ArtSchoolDetailController extends BaseController {

    private final IArtSchoolDetailService artSchoolDetailService;

    /**
     * 查询学校详细信息列表
     */
    @SaCheckPermission("art:schoolDetail:list")
    @GetMapping("/list")
    public TableDataInfo<ArtSchoolDetailVo> list(ArtSchoolDetailBo bo, PageQuery pageQuery) {
        return artSchoolDetailService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出学校详细信息列表
     */
    @SaCheckPermission("art:schoolDetail:export")
    @Log(title = "学校详细信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(ArtSchoolDetailBo bo, HttpServletResponse response) {
        List<ArtSchoolDetailVo> list = artSchoolDetailService.queryList(bo);
        ExcelUtil.exportExcel(list, "学校详细信息", ArtSchoolDetailVo.class, response);
    }

    /**
     * 获取学校详细信息详细信息
     *
     * @param detailId 主键
     */
    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/{detailId}")
    public R<ArtSchoolDetailVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long detailId) {
        return R.ok(artSchoolDetailService.queryById(detailId));
    }

    /**
     * 新增学校详细信息
     */
    @SaCheckPermission("art:schoolDetail:add")
    @Log(title = "学校详细信息", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody ArtSchoolDetailBo bo) {
        return toAjax(artSchoolDetailService.insertByBo(bo));
    }

    /**
     * 修改学校详细信息
     */
    @SaCheckPermission("art:schoolDetail:edit")
    @Log(title = "学校详细信息", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ArtSchoolDetailBo bo) {
        return toAjax(artSchoolDetailService.updateByBo(bo));
    }

    /**
     * 删除学校详细信息
     *
     * @param detailIds 主键串
     */
    @SaCheckPermission("art:schoolDetail:remove")
    @Log(title = "学校详细信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{detailIds}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] detailIds) {
        return toAjax(artSchoolDetailService.deleteWithValidByIds(List.of(detailIds), Boolean.TRUE));
    }

    // ------------------------ JSONB 独立接口 ------------------------

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/satisfaction")
    public R<Map<String, Object>> getSatisfactionJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return R.ok(Map.of("satisfactionJson", parseJson(getDetailValue(schoolId, DetailField.SATISFACTION))));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/satisfaction")
    public R<Void> saveSatisfactionJson(@Validated @RequestBody SatisfactionJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.SATISFACTION, toJsonString(request.getSatisfactionJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/satisfaction")
    public R<Void> deleteSatisfactionJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.SATISFACTION, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/scholarship")
    public R<Map<String, Object>> getScholarshipJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return R.ok(Map.of("scholarshipJson", parseJson(getDetailValue(schoolId, DetailField.SCHOLARSHIP))));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/scholarship")
    public R<Void> saveScholarshipJson(@Validated @RequestBody ScholarshipJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.SCHOLARSHIP, toJsonString(request.getScholarshipJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/scholarship")
    public R<Void> deleteScholarshipJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.SCHOLARSHIP, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/specialMajor")
    public R<Map<String, Object>> getSpecialMajorJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return R.ok(Map.of("specialMajorJson", parseJson(getDetailValue(schoolId, DetailField.SPECIAL_MAJOR))));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/specialMajor")
    public R<Void> saveSpecialMajorJson(@Validated @RequestBody SpecialMajorJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.SPECIAL_MAJOR, toJsonString(request.getSpecialMajorJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/specialMajor")
    public R<Void> deleteSpecialMajorJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.SPECIAL_MAJOR, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/employmentReport")
    public R<Map<String, Object>> getEmploymentReportJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return R.ok(Map.of("employmentReportJson", parseJson(getDetailValue(schoolId, DetailField.EMPLOYMENT_REPORT))));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/employmentReport")
    public R<Void> saveEmploymentReportJson(@Validated @RequestBody EmploymentReportJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.EMPLOYMENT_REPORT, toJsonString(request.getEmploymentReportJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/employmentReport")
    public R<Void> deleteEmploymentReportJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.EMPLOYMENT_REPORT, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/photo")
    public R<Map<String, Object>> getPhotoJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return R.ok(Map.of("photoJson", parseJson(getDetailValue(schoolId, DetailField.PHOTO))));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/photo")
    public R<Void> savePhotoJson(@Validated @RequestBody PhotoJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.PHOTO, toJsonString(request.getPhotoJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/photo")
    public R<Void> deletePhotoJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.PHOTO, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/accommodation")
    public R<Map<String, Object>> getAccommodationJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return R.ok(Map.of("accommodationJson", parseJson(getDetailValue(schoolId, DetailField.ACCOMMODATION))));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/accommodation")
    public R<Void> saveAccommodationJson(@Validated @RequestBody AccommodationJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.ACCOMMODATION, toJsonString(request.getAccommodationJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/accommodation")
    public R<Void> deleteAccommodationJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.ACCOMMODATION, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/subjectReviews")
    public R<Map<String, Object>> getSubjectReviewsJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return R.ok(Map.of("subjectReviewsJson", parseJson(getDetailValue(schoolId, DetailField.SUBJECT_REVIEWS))));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/subjectReviews")
    public R<Void> saveSubjectReviewsJson(@Validated @RequestBody SubjectReviewsJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.SUBJECT_REVIEWS, toJsonString(request.getSubjectReviewsJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/subjectReviews")
    public R<Void> deleteSubjectReviewsJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.SUBJECT_REVIEWS, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/research")
    public R<Map<String, Object>> getResearchJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return R.ok(Map.of("researchJson", parseJson(getDetailValue(schoolId, DetailField.RESEARCH))));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/research")
    public R<Void> saveResearchJson(@Validated @RequestBody ResearchJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.RESEARCH, toJsonString(request.getResearchJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/research")
    public R<Void> deleteResearchJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.RESEARCH, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/univMajors")
    public R<Map<String, Object>> getUnivMajorsJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return R.ok(Map.of("univMajorsJson", parseJson(getDetailValue(schoolId, DetailField.UNIV_MAJORS))));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/univMajors")
    public R<Void> saveUnivMajorsJson(@Validated @RequestBody UnivMajorsJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.UNIV_MAJORS, toJsonString(request.getUnivMajorsJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/univMajors")
    public R<Void> deleteUnivMajorsJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.UNIV_MAJORS, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/univPostgraduate")
    public R<Map<String, Object>> getUnivPostgraduateJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        Object o = parseJson(getDetailValue(schoolId, DetailField.UNIV_POSTGRADUATE));
        return R.ok(Map.of("univPostgraduateJson", o));
    }

    @SaCheckPermission("art:schoolDetail:edit")
    @PutMapping("/json/univPostgraduate")
    public R<Void> saveUnivPostgraduateJson(@Validated @RequestBody UnivPostgraduateJsonRequest request) {
        return toAjax(saveDetailValue(request.getSchoolId(), DetailField.UNIV_POSTGRADUATE, toJsonString(request.getUnivPostgraduateJson())));
    }

    @SaCheckPermission("art:schoolDetail:remove")
    @DeleteMapping("/json/univPostgraduate")
    public R<Void> deleteUnivPostgraduateJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        return toAjax(saveDetailValue(schoolId, DetailField.UNIV_POSTGRADUATE, null));
    }

    @SaCheckPermission("art:schoolDetail:query")
    @GetMapping("/json/all")
    public R<Map<String, Object>> getAllJson(@NotNull(message = "学校ID不能为空") @RequestParam Long schoolId) {
        ArtSchoolDetail detail = artSchoolDetailService.queryEntityBySchoolId(schoolId);
        if (detail == null) {
            return R.ok(Map.of());
        }
        return R.ok(Map.of(
            "satisfactionJson", parseJson(detail.getSatisfactionJson()),
            "scholarshipJson", parseJson(detail.getScholarshipJson()),
            "specialMajorJson", parseJson(detail.getSpecialMajorJson()),
            "employmentReportJson", parseJson(detail.getEmploymentReportJson()),
            "photoJson", parseJson(detail.getPhotoJson()),
            "accommodationJson", parseJson(detail.getAccommodationJson()),
            "subjectReviewsJson", parseJson(detail.getSubjectReviewsJson()),
            "researchJson", parseJson(detail.getResearchJson()),
            "univMajorsJson", parseJson(detail.getUnivMajorsJson()),
            "univPostgraduateJson", parseJson(detail.getUnivPostgraduateJson())
        ));
    }

    private String getDetailValue(Long schoolId, DetailField field) {
        ArtSchoolDetail detail = artSchoolDetailService.queryEntityBySchoolId(schoolId);
        if (detail == null) {
            return null;
        }
        return switch (field) {
            case SATISFACTION -> detail.getSatisfactionJson();
            case SCHOLARSHIP -> detail.getScholarshipJson();
            case SPECIAL_MAJOR -> detail.getSpecialMajorJson();
            case EMPLOYMENT_REPORT -> detail.getEmploymentReportJson();
            case PHOTO -> detail.getPhotoJson();
            case ACCOMMODATION -> detail.getAccommodationJson();
            case SUBJECT_REVIEWS -> detail.getSubjectReviewsJson();
            case RESEARCH -> detail.getResearchJson();
            case UNIV_MAJORS -> detail.getUnivMajorsJson();
            case UNIV_POSTGRADUATE -> detail.getUnivPostgraduateJson();
        };
    }

    private boolean saveDetailValue(Long schoolId, DetailField field, String json) {
        ArtSchoolDetail detail = artSchoolDetailService.queryEntityBySchoolId(schoolId);
        if (detail == null) {
            detail = new ArtSchoolDetail();
            detail.setSchoolId(schoolId);
        }
        switch (field) {
            case SATISFACTION -> detail.setSatisfactionJson(json);
            case SCHOLARSHIP -> detail.setScholarshipJson(json);
            case SPECIAL_MAJOR -> detail.setSpecialMajorJson(json);
            case EMPLOYMENT_REPORT -> detail.setEmploymentReportJson(json);
            case PHOTO -> detail.setPhotoJson(json);
            case ACCOMMODATION -> detail.setAccommodationJson(json);
            case SUBJECT_REVIEWS -> detail.setSubjectReviewsJson(json);
            case RESEARCH -> detail.setResearchJson(json);
            case UNIV_MAJORS -> detail.setUnivMajorsJson(json);
            case UNIV_POSTGRADUATE -> detail.setUnivPostgraduateJson(json);
        }
        return artSchoolDetailService.saveOrUpdateBySchoolId(detail);
    }

    private Object parseJson(String json) {
        if (json == null || json.isBlank()) {
            return null;
        }
        try {
            return JsonUtils.getObjectMapper().readTree(json);
        } catch (Exception e) {
            return json;
        }
    }

    private String toJsonString(JsonNode node) {
        if (node == null || node.isNull()) {
            return null;
        }
        return JsonUtils.toJsonString(node);
    }

    private enum DetailField {
        SATISFACTION,
        SCHOLARSHIP,
        SPECIAL_MAJOR,
        EMPLOYMENT_REPORT,
        PHOTO,
        ACCOMMODATION,
        SUBJECT_REVIEWS,
        RESEARCH,
        UNIV_MAJORS,
        UNIV_POSTGRADUATE
    }

    public static class SatisfactionJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode satisfactionJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getSatisfactionJson() {
            return satisfactionJson;
        }

        public void setSatisfactionJson(JsonNode satisfactionJson) {
            this.satisfactionJson = satisfactionJson;
        }
    }

    public static class ScholarshipJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode scholarshipJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getScholarshipJson() {
            return scholarshipJson;
        }

        public void setScholarshipJson(JsonNode scholarshipJson) {
            this.scholarshipJson = scholarshipJson;
        }
    }

    public static class SpecialMajorJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode specialMajorJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getSpecialMajorJson() {
            return specialMajorJson;
        }

        public void setSpecialMajorJson(JsonNode specialMajorJson) {
            this.specialMajorJson = specialMajorJson;
        }
    }

    public static class EmploymentReportJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode employmentReportJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getEmploymentReportJson() {
            return employmentReportJson;
        }

        public void setEmploymentReportJson(JsonNode employmentReportJson) {
            this.employmentReportJson = employmentReportJson;
        }
    }

    public static class PhotoJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode photoJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getPhotoJson() {
            return photoJson;
        }

        public void setPhotoJson(JsonNode photoJson) {
            this.photoJson = photoJson;
        }
    }

    public static class AccommodationJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode accommodationJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getAccommodationJson() {
            return accommodationJson;
        }

        public void setAccommodationJson(JsonNode accommodationJson) {
            this.accommodationJson = accommodationJson;
        }
    }

    public static class SubjectReviewsJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode subjectReviewsJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getSubjectReviewsJson() {
            return subjectReviewsJson;
        }

        public void setSubjectReviewsJson(JsonNode subjectReviewsJson) {
            this.subjectReviewsJson = subjectReviewsJson;
        }
    }

    public static class ResearchJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode researchJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getResearchJson() {
            return researchJson;
        }

        public void setResearchJson(JsonNode researchJson) {
            this.researchJson = researchJson;
        }
    }

    public static class UnivMajorsJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode univMajorsJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getUnivMajorsJson() {
            return univMajorsJson;
        }

        public void setUnivMajorsJson(JsonNode univMajorsJson) {
            this.univMajorsJson = univMajorsJson;
        }
    }

    public static class UnivPostgraduateJsonRequest {
        @NotNull(message = "学校ID不能为空")
        private Long schoolId;
        private JsonNode univPostgraduateJson;

        public Long getSchoolId() {
            return schoolId;
        }

        public void setSchoolId(Long schoolId) {
            this.schoolId = schoolId;
        }

        public JsonNode getUnivPostgraduateJson() {
            return univPostgraduateJson;
        }

        public void setUnivPostgraduateJson(JsonNode univPostgraduateJson) {
            this.univPostgraduateJson = univPostgraduateJson;
        }
    }
}
