package com.nursinghome.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.nursinghome.common.ApiException;
import com.nursinghome.common.ApiResponse;
import com.nursinghome.dto.*;
import com.nursinghome.entity.*;
import com.nursinghome.mapper.*;
import com.nursinghome.service.BillService;
import com.nursinghome.service.ElderService;
import com.nursinghome.service.UserService;
import com.nursinghome.util.PasswordUtil;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/admin")
@SaCheckRole("ADMIN")
public class AdminController {
    private final UserService userService;
    private final ElderService elderService;
    private final ScheduleMapper scheduleMapper;
    private final FeedbackMapper feedbackMapper;
    private final NoticeMapper noticeMapper;
    private final BillService billService;
    private final BillMapper billMapper;
    private final UserMapper userMapper;

    public AdminController(UserService userService,
                           ElderService elderService,
                           ScheduleMapper scheduleMapper,
                           FeedbackMapper feedbackMapper,
                           NoticeMapper noticeMapper,
                           BillService billService,
                           BillMapper billMapper,
                           UserMapper userMapper) {
        this.userService = userService;
        this.elderService = elderService;
        this.scheduleMapper = scheduleMapper;
        this.feedbackMapper = feedbackMapper;
        this.noticeMapper = noticeMapper;
        this.billService = billService;
        this.billMapper = billMapper;
        this.userMapper = userMapper;
    }

    @GetMapping("/stats")
    public ApiResponse<Map<String, Object>> stats() {
        int elders = elderService.listAll().size();
        int nurses = userService.listByRole("NURSE").size();
        int families = userService.listByRole("FAMILY").size();
        BigDecimal income = BigDecimal.ZERO;
        for (Bill bill : billMapper.listAll()) {
            if ("PAID".equals(bill.getStatus()) && bill.getTotal() != null) {
                income = income.add(bill.getTotal());
            }
        }
        Map<String, Object> data = new HashMap<>();
        data.put("elders", elders);
        data.put("nurses", nurses);
        data.put("families", families);
        data.put("income", income);
        return ApiResponse.success(data);
    }

    @GetMapping("/users")
    public ApiResponse<List<User>> listUsers(@RequestParam(required = false) String role) {
        List<User> users = userService.listByRole(role);
        for (User user : users) {
            user.setPassword(null);
        }
        return ApiResponse.success(users);
    }

    @PostMapping("/users")
    public ApiResponse<User> createUser(@RequestBody UserRequest request) {
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(request.getPassword());
        user.setName(request.getName());
        user.setPhone(request.getPhone());
        user.setRole(request.getRole());
        user.setStatus(request.getStatus() == null ? 1 : request.getStatus());
        userService.createUser(user, true);
        user.setPassword(null);
        return ApiResponse.success(user);
    }

    @PutMapping("/users")
    public ApiResponse<Void> updateUser(@RequestBody UserUpdateRequest request) {
        User user = new User();
        user.setId(request.getId());
        user.setName(request.getName());
        user.setPhone(request.getPhone());
        user.setStatus(request.getStatus());
        userService.updateUser(user);
        return ApiResponse.success();
    }

    @PutMapping("/users/{id}/status")
    public ApiResponse<Void> updateUserStatus(@PathVariable Long id, @RequestParam Integer status) {
        userService.updateStatus(id, status);
        return ApiResponse.success();
    }

    @PostMapping("/users/{id}/reset-password")
    public ApiResponse<Void> resetPassword(@PathVariable Long id, @RequestParam String password) {
        userService.updatePassword(id, PasswordUtil.hash(password));
        return ApiResponse.success();
    }

    @GetMapping("/elders")
    public ApiResponse<List<Elder>> listElders() {
        return ApiResponse.success(elderService.listAll());
    }

    @PostMapping("/elders")
    public ApiResponse<Elder> createElder(@RequestBody ElderRequest request) {
        Elder elder = new Elder();
        elder.setName(request.getName());
        elder.setGender(request.getGender());
        elder.setIdCard(request.getIdCard());
        elder.setBirthday(request.getBirthday());
        elder.setRoomNo(request.getRoomNo());
        elder.setCheckInDate(request.getCheckInDate());
        elder.setCareLevel(request.getCareLevel());
        elder.setStatus(request.getStatus());
        elder.setRemark(request.getRemark());
        return ApiResponse.success(elderService.create(elder));
    }

    @PutMapping("/elders")
    public ApiResponse<Void> updateElder(@RequestBody ElderRequest request) {
        Elder elder = new Elder();
        elder.setId(request.getId());
        elder.setName(request.getName());
        elder.setGender(request.getGender());
        elder.setIdCard(request.getIdCard());
        elder.setBirthday(request.getBirthday());
        elder.setRoomNo(request.getRoomNo());
        elder.setCheckInDate(request.getCheckInDate());
        elder.setCareLevel(request.getCareLevel());
        elder.setStatus(request.getStatus());
        elder.setRemark(request.getRemark());
        elderService.update(elder);
        return ApiResponse.success();
    }

    @DeleteMapping("/elders/{id}")
    public ApiResponse<Void> deleteElder(@PathVariable Long id) {
        elderService.delete(id);
        return ApiResponse.success();
    }

    @GetMapping("/schedules")
    public ApiResponse<List<Schedule>> listSchedules(@RequestParam String date) {
        return ApiResponse.success(scheduleMapper.listByDate(java.time.LocalDate.parse(date)));
    }

    @GetMapping("/schedules/range")
    public ApiResponse<List<Schedule>> listSchedulesRange(@RequestParam String start, @RequestParam String end) {
        return ApiResponse.success(scheduleMapper.listByDateRange(
            java.time.LocalDate.parse(start),
            java.time.LocalDate.parse(end)
        ));
    }

    @PostMapping("/schedules")
    public ApiResponse<Schedule> createSchedule(@RequestBody ScheduleRequest request) {
        Schedule schedule = new Schedule();
        schedule.setNurseId(request.getNurseId());
        schedule.setDate(request.getDate());
        schedule.setShift(request.getShift());
        schedule.setTask(request.getTask());
        scheduleMapper.insert(schedule);
        return ApiResponse.success(schedule);
    }

    @PutMapping("/schedules")
    public ApiResponse<Void> updateSchedule(@RequestBody ScheduleRequest request) {
        Schedule schedule = new Schedule();
        schedule.setId(request.getId());
        schedule.setNurseId(request.getNurseId());
        schedule.setDate(request.getDate());
        schedule.setShift(request.getShift());
        schedule.setTask(request.getTask());
        scheduleMapper.update(schedule);
        return ApiResponse.success();
    }

    @DeleteMapping("/schedules/{id}")
    public ApiResponse<Void> deleteSchedule(@PathVariable Long id) {
        scheduleMapper.delete(id);
        return ApiResponse.success();
    }

    @PostMapping("/bills")
    public ApiResponse<Bill> createBill(@RequestBody BillRequest request) {
        Bill bill = new Bill();
        bill.setElderId(request.getElderId());
        bill.setMonth(request.getMonth());
        bill.setBedFee(request.getBedFee());
        bill.setCareFee(request.getCareFee());
        bill.setMealFee(request.getMealFee());
        bill.setOtherFee(request.getOtherFee());
        return ApiResponse.success(billService.createBill(bill));
    }

    @PutMapping("/bills")
    public ApiResponse<Void> updateBill(@RequestBody BillRequest request) {
        Bill existing = billMapper.findById(request.getId());
        if (existing == null) {
            throw new ApiException("账单不存在");
        }
        Bill bill = new Bill();
        bill.setId(request.getId());
        bill.setElderId(request.getElderId());
        bill.setMonth(request.getMonth());
        bill.setBedFee(request.getBedFee());
        bill.setCareFee(request.getCareFee());
        bill.setMealFee(request.getMealFee());
        bill.setOtherFee(request.getOtherFee());
        bill.setTotal(billService.calcTotal(bill));
        bill.setStatus(existing.getStatus());
        billMapper.update(bill);
        return ApiResponse.success();
    }

    @GetMapping("/bills")
    public ApiResponse<List<Bill>> listBills(@RequestParam(required = false) Long elderId) {
        if (elderId == null) {
            return ApiResponse.success(billMapper.listAll());
        }
        return ApiResponse.success(billService.listByElderId(elderId));
    }

    @DeleteMapping("/bills/{id}")
    public ApiResponse<Void> deleteBill(@PathVariable Long id) {
        Bill existing = billMapper.findById(id);
        if (existing == null) {
            throw new ApiException("账单不存在");
        }
        billMapper.delete(id);
        return ApiResponse.success();
    }

    @GetMapping("/feedback")
    public ApiResponse<List<Feedback>> listFeedback() {
        return ApiResponse.success(feedbackMapper.listAll());
    }

    @PutMapping("/feedback")
    public ApiResponse<Void> updateFeedback(@RequestBody FeedbackUpdateRequest request) {
        Feedback feedback = new Feedback();
        feedback.setId(request.getId());
        feedback.setStatus(request.getStatus());
        feedback.setReply(request.getReply());
        feedbackMapper.updateStatus(feedback);
        return ApiResponse.success();
    }

    @PostMapping("/notices")
    public ApiResponse<Notice> createNotice(@RequestBody NoticeRequest request) {
        Notice notice = new Notice();
        notice.setTitle(request.getTitle());
        notice.setContent(request.getContent());
        notice.setTargetRole(request.getTargetRole());
        notice.setTargetUserId(request.getTargetUserId());
        notice.setCreatedBy(Long.valueOf(StpUtil.getLoginId().toString()));
        noticeMapper.insert(notice);
        return ApiResponse.success(notice);
    }

    @GetMapping("/notices")
    public ApiResponse<List<Notice>> listNotices(@RequestParam(required = false) String role,
                                                 @RequestParam(required = false) Long userId) {
        return ApiResponse.success(noticeMapper.listByTarget(role, userId));
    }
}
