package com.mosquito.project.controller;

import com.mosquito.project.dto.ApiResponse;
import com.mosquito.project.permission.ApprovalFlowService;
import com.mosquito.project.permission.RequirePermission;
import com.mosquito.project.persistence.entity.UserInviteEntity;
import com.mosquito.project.persistence.repository.UserInviteRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 邀请用户控制器
 */
@RestController
@RequestMapping("/api/v1/invites")
public class InviteController {

    private static final Logger log = LoggerFactory.getLogger(InviteController.class);

    private final UserInviteRepository userInviteRepository;
    private final ApprovalFlowService approvalFlowService;

    public InviteController(UserInviteRepository userInviteRepository, ApprovalFlowService approvalFlowService) {
        this.userInviteRepository = userInviteRepository;
        this.approvalFlowService = approvalFlowService;
    }

    /**
     * 从请求属性中获取当前用户ID
     */
    private Long getCurrentUserId(HttpServletRequest request) {
        Object userIdObj = request.getAttribute("userId");
        if (userIdObj instanceof Long) {
            return (Long) userIdObj;
        } else if (userIdObj instanceof Integer) {
            return ((Integer) userIdObj).longValue();
        } else if (userIdObj instanceof String) {
            try {
                return Long.parseLong((String) userIdObj);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 获取邀请列表
     */
    @GetMapping
    @RequirePermission("user.index.view.ALL")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getInvites(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String query,
            HttpServletRequest request) {

        Long currentUserId = getCurrentUserId(request);
        if (currentUserId == null) {
            return ResponseEntity.status(401).body(ApiResponse.error(401, "未登录或token无效"));
        }

        PageRequest pageRequest = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "invitedAt"));
        Page<UserInviteEntity> invitesPage;

        if (query != null && !query.isEmpty()) {
            invitesPage = userInviteRepository.findByEmailContaining(query, pageRequest);
        } else if (status != null && !status.isEmpty()) {
            invitesPage = userInviteRepository.findByStatus(status, pageRequest);
        } else {
            invitesPage = userInviteRepository.findAll(pageRequest);
        }

        List<Map<String, Object>> invites = invitesPage.getContent().stream()
                .map(this::convertToMap)
                .toList();

        Map<String, Object> result = new HashMap<>();
        result.put("items", invites);  // 兼容前端 items 字段
        result.put("data", invites);
        result.put("total", invitesPage.getTotalElements());
        result.put("page", page + 1);
        result.put("size", size);
        result.put("totalPages", invitesPage.getTotalPages());

        return ResponseEntity.ok(ApiResponse.success(result));
    }

    /**
     * 创建邀请
     */
    @PostMapping
    @RequirePermission("user.index.create.ALL")
    public ResponseEntity<ApiResponse<Map<String, Object>>> createInvite(
            @Valid @RequestBody InviteRequest request,
            HttpServletRequest httpRequest) {

        Long currentUserId = getCurrentUserId(httpRequest);
        if (currentUserId == null) {
            return ResponseEntity.status(401).body(ApiResponse.error(401, "未登录或token无效"));
        }

        UserInviteEntity invite = new UserInviteEntity();
        invite.setEmail(request.getEmail());
        invite.setRole(request.getRole());
        invite.setInvitedBy(currentUserId);
        invite.setStatus("PENDING");
        invite.setInvitedAt(OffsetDateTime.now(ZoneOffset.ofHours(8)));
        invite.setExpiredAt(OffsetDateTime.now(ZoneOffset.ofHours(8)).plusDays(7));

        UserInviteEntity saved = userInviteRepository.save(invite);

        log.info("创建邀请: email={}, role={}, invitedBy={}", request.getEmail(), request.getRole(), currentUserId);

        return ResponseEntity.ok(ApiResponse.success(convertToMap(saved), "邀请创建成功"));
    }

    /**
     * 重发邀请
     */
    @PostMapping("/{id}/resend")
    @RequirePermission("user.index.update.ALL")
    public ResponseEntity<ApiResponse<Void>> resendInvite(
            @PathVariable Long id,
            HttpServletRequest request) {

        Long currentUserId = getCurrentUserId(request);
        if (currentUserId == null) {
            return ResponseEntity.status(401).body(ApiResponse.error(401, "未登录或token无效"));
        }

        return userInviteRepository.findById(id)
                .<ResponseEntity<ApiResponse<Void>>>map(invite -> {
                    invite.setInvitedAt(OffsetDateTime.now(ZoneOffset.ofHours(8)));
                    invite.setExpiredAt(OffsetDateTime.now(ZoneOffset.ofHours(8)).plusDays(7));
                    userInviteRepository.save(invite);
                    log.info("重发邀请: id={}, email={}, operator={}", id, invite.getEmail(), currentUserId);
                    return ResponseEntity.ok(ApiResponse.success(null, "邀请重发成功"));
                })
                .orElse(ResponseEntity.ok(ApiResponse.error(404, "邀请记录不存在")));
    }

    /**
     * 设置邀请过期
     */
    @PostMapping("/{id}/expire")
    @RequirePermission("user.index.update.ALL")
    public ResponseEntity<ApiResponse<Void>> expireInvite(
            @PathVariable Long id,
            HttpServletRequest request) {

        Long currentUserId = getCurrentUserId(request);
        if (currentUserId == null) {
            return ResponseEntity.status(401).body(ApiResponse.error(401, "未登录或token无效"));
        }

        return userInviteRepository.findById(id)
                .<ResponseEntity<ApiResponse<Void>>>map(invite -> {
                    invite.setStatus("EXPIRED");
                    userInviteRepository.save(invite);
                    log.info("设置邀请过期: id={}, email={}, operator={}", id, invite.getEmail(), currentUserId);
                    return ResponseEntity.ok(ApiResponse.success(null, "邀请已设置为过期"));
                })
                .orElse(ResponseEntity.ok(ApiResponse.<Void>error(404, "邀请记录不存在")));
    }

    /**
     * 删除邀请
     */
    @DeleteMapping("/{id}")
    @RequirePermission("user.index.delete.ALL")
    public ResponseEntity<ApiResponse<Void>> deleteInvite(
            @PathVariable Long id,
            HttpServletRequest request) {

        Long currentUserId = getCurrentUserId(request);
        if (currentUserId == null) {
            return ResponseEntity.status(401).body(ApiResponse.error(401, "未登录或token无效"));
        }

        if (!userInviteRepository.existsById(id)) {
            return ResponseEntity.ok(ApiResponse.error(404, "邀请记录不存在"));
        }
        userInviteRepository.deleteById(id);
        log.info("删除邀请: id={}, operator={}", id, currentUserId);
        return ResponseEntity.ok(ApiResponse.success(null, "邀请删除成功"));
    }

    private Map<String, Object> convertToMap(UserInviteEntity invite) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", invite.getId());
        map.put("email", invite.getEmail());
        map.put("role", invite.getRole());
        map.put("status", invite.getStatus());
        map.put("invitedAt", invite.getInvitedAt() != null ? invite.getInvitedAt().toString() : null);
        map.put("expiredAt", invite.getExpiredAt() != null ? invite.getExpiredAt().toString() : null);
        return map;
    }

    public static class InviteRequest {
        @NotBlank(message = "邮箱不能为空")
        @Email(message = "邮箱格式不正确")
        private String email;

        @NotBlank(message = "角色不能为空")
        private String role;

        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        public String getRole() { return role; }
        public void setRole(String role) { this.role = role; }
    }
}
