package com.lesingle.edu.controller.admin;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lesingle.edu.common.annotation.Log;
import com.lesingle.edu.common.enums.LogModule;
import com.lesingle.edu.common.enums.LogOperationType;
import com.lesingle.edu.common.annotation.RequireRole;
import com.lesingle.edu.common.enums.UserRole;
import com.lesingle.edu.common.response.PageResult;
import com.lesingle.edu.common.response.Result;
import com.lesingle.edu.dto.request.TenantCreateRequest;
import com.lesingle.edu.dto.request.TenantUpdateRequest;
import com.lesingle.edu.dto.request.UpdateTenantQuotaRequest;
import com.lesingle.edu.dto.response.TenantResponse;
import com.lesingle.edu.entity.Tenant;
import com.lesingle.edu.entity.TenantPackage;
import com.lesingle.edu.entity.CourseCollection;
import com.lesingle.edu.mapper.TenantPackageMapper;
import com.lesingle.edu.mapper.CourseCollectionMapper;
import com.lesingle.edu.service.TenantService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Tag(name = "超管端 - 租户管理", description = "Tenant Management APIs for Admin")
@RestController
@RequestMapping("/api/v1/admin/tenants")
@RequiredArgsConstructor
@RequireRole(UserRole.ADMIN)
public class AdminTenantController {

    private final TenantService tenantService;
    private final TenantPackageMapper tenantPackageMapper;
    private final CourseCollectionMapper collectionMapper;

    @Operation(summary = "Create tenant")
    @Log(module = LogModule.TENANT, type = LogOperationType.CREATE, description = "创建租户")
    @PostMapping
    public Result<TenantResponse> createTenant(@Valid @RequestBody TenantCreateRequest request) {
        Tenant tenant = tenantService.createTenant(request);
        return Result.success(toResponse(tenant));
    }

    @Operation(summary = "Update tenant")
    @Log(module = LogModule.TENANT, type = LogOperationType.UPDATE, description = "修改租户")
    @PutMapping("/{id}")
    public Result<TenantResponse> updateTenant(@PathVariable Long id, @RequestBody TenantUpdateRequest request) {
        Tenant tenant = tenantService.updateTenant(id, request);
        return Result.success(toResponse(tenant));
    }

    @Operation(summary = "Get tenant by ID")
    @GetMapping("/{id}")
    public Result<TenantResponse> getTenant(@PathVariable Long id) {
        TenantResponse tenant = tenantService.getTenantDetail(id);
        return Result.success(tenant);
    }

    @Operation(summary = "Get tenant page")
    @GetMapping
    public Result<PageResult<TenantResponse>> getTenantPage(
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String status) {
        // 调用 Service 层方法获取带统计数据的租户分页
        Page<TenantResponse> pageResult = tenantService.getTenantPageWithStats(pageNum, pageSize, keyword, status);

        return Result.success(PageResult.of(
                pageResult.getRecords(),
                pageResult.getTotal(),
                pageResult.getCurrent(),
                pageResult.getSize()
        ));
    }

    @Operation(summary = "Delete tenant")
    @Log(module = LogModule.TENANT, type = LogOperationType.DELETE, description = "删除租户")
    @DeleteMapping("/{id}")
    public Result<Void> deleteTenant(@PathVariable Long id) {
        tenantService.deleteTenant(id);
        return Result.success();
    }

    @Operation(summary = "Get all active tenants")
    @GetMapping("/active")
    public Result<List<TenantResponse>> getAllActiveTenants() {
        List<Tenant> tenants = tenantService.getAllActiveTenants();
        List<TenantResponse> responses = tenants.stream()
                .map(this::toResponse)
                .collect(Collectors.toList());
        return Result.success(responses);
    }

    @Operation(summary = "获取租户统计信息")
    @GetMapping("/stats")
    public Result<Map<String, Object>> getTenantStats() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalTenants", 0);
        stats.put("activeTenants", 0);
        stats.put("inactiveTenants", 0);
        return Result.success(stats);
    }

    @Operation(summary = "更新租户配额")
    @Log(module = LogModule.TENANT, type = LogOperationType.UPDATE, description = "更新租户配额")
    @PutMapping("/{id}/quota")
    public Result<TenantResponse> updateTenantQuota(
            @PathVariable Long id,
            @RequestBody UpdateTenantQuotaRequest request) {
        TenantUpdateRequest updateRequest = new TenantUpdateRequest();
        updateRequest.setCollectionIds(request.getCollectionIds());
        updateRequest.setTeacherQuota(request.getTeacherQuota());
        updateRequest.setStudentQuota(request.getStudentQuota());
        Tenant tenant = tenantService.updateTenant(id, updateRequest);
        return Result.success(toResponse(tenant));
    }

    @Operation(summary = "更新租户状态")
    @Log(module = LogModule.TENANT, type = LogOperationType.UPDATE, description = "更新租户状态")
    @PutMapping("/{id}/status")
    public Result<TenantResponse> updateTenantStatus(@PathVariable Long id, @RequestBody Map<String, Object> status) {
        String newStatus = (String) status.get("status");
        tenantService.updateTenantStatus(id, newStatus);
        Tenant tenant = tenantService.getTenantById(id);
        return Result.success(toResponse(tenant));
    }

    @Operation(summary = "重置租户密码")
    @Log(module = LogModule.TENANT, type = LogOperationType.UPDATE, description = "重置租户密码")
    @PostMapping("/{id}/reset-password")
    public Result<Map<String, String>> resetTenantPassword(@PathVariable Long id) {
        String tempPassword = tenantService.resetPasswordAndReturnTemp(id);
        return Result.success(Map.of("tempPassword", tempPassword));
    }

    /**
     * 将 Tenant 实体转换为 TenantResponse（包含套餐名称列表）
     */
    private TenantResponse toResponse(Tenant tenant) {
        // 从 tenant_package 表查询所有套餐信息（只查询 ACTIVE 状态的关联）
        List<TenantPackage> tenantPackages = tenantPackageMapper.selectList(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<TenantPackage>()
                        .eq(TenantPackage::getTenantId, tenant.getId())
                        .eq(TenantPackage::getStatus, com.lesingle.edu.common.enums.TenantPackageStatus.ACTIVE)
                        .orderByDesc(TenantPackage::getStartDate)
        );

        // 获取所有关联的套餐名称列表
        List<String> packageNames = new ArrayList<>();
        for (TenantPackage tp : tenantPackages) {
            if (tp.getCollectionId() != null) {
                CourseCollection collection = collectionMapper.selectById(tp.getCollectionId());
                if (collection != null) {
                    packageNames.add(collection.getName());
                }
            }
        }

        return TenantResponse.builder()
                .id(tenant.getId())
                .name(tenant.getName())
                .code(tenant.getCode())
                .username(tenant.getUsername())
                .contactName(tenant.getContactName())
                .contactPhone(tenant.getContactPhone())
                .contactEmail(tenant.getContactEmail())
                .address(tenant.getAddress())
                .logoUrl(tenant.getLogoUrl())
                .status(tenant.getStatus())
                .expireAt(tenant.getExpireAt())
                .maxStudents(tenant.getMaxStudents())
                .maxTeachers(tenant.getMaxTeachers())
                .packageNames(packageNames)  // 套餐名称列表
                .teacherQuota(tenant.getTeacherQuota())
                .studentQuota(tenant.getStudentQuota())
                .storageQuota(tenant.getStorageQuota())
                .storageUsed(tenant.getStorageUsed())
                .startDate(tenant.getStartDate())
                .expireDate(tenant.getExpireDate())
                .createdAt(tenant.getCreatedAt())
                .updatedAt(tenant.getUpdatedAt())
                .build();
    }

}