package com.moka.gdtauto.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.moka.gdtauto.annotation.AuthUser;
import com.moka.gdtauto.common.Result;
import com.moka.gdtauto.controller.vo.CreateAdPlanConfRequest;
import com.moka.gdtauto.controller.vo.UpdateAdPlanConfRequest;
import com.moka.gdtauto.entity.AccountGroup;
import com.moka.gdtauto.entity.AccountGroupAccountRelationship;
import com.moka.gdtauto.entity.AdPlanConf;
import com.moka.gdtauto.entity.SysUser;
import com.moka.gdtauto.entity.AdPlan;
import com.moka.gdtauto.entity.AdPlanCreative;
import com.moka.gdtauto.service.SysUserService;

import com.moka.gdtauto.mapper.AccountGroupAccountRelationshipMapper;
import com.moka.gdtauto.service.AccountGroupService;
import com.moka.gdtauto.service.AdPlanConfService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 广告计划配置管理控制器
 * 
 * @author moka
 * @since 2026-02-24
 */
@Tag(name = "广告计划配置管理", description = "广告计划配置的创建、更新、删除及查询")
@Slf4j
@RestController
@RequestMapping("/api/ad-plan-conf")
@RequiredArgsConstructor
public class AdPlanConfController {

    private final AdPlanConfService adPlanConfService;
    private final AccountGroupAccountRelationshipMapper relationshipMapper;
    private final SysUserService sysUserService;
    private final AccountGroupService accountGroupService;

    @Operation(summary = "预创建广告计划配置", description = "根据账户分组ID和配置ID，重新创建广告计划配置")
    @PostMapping("/reCreate")
    public Result<List<AdPlan>> reCreateAdPlanConf(
            @RequestBody UpdateAdPlanConfRequest request,
            @AuthUser SysUser sysUser) {
        try {
            AccountGroup accountGroup = accountGroupService.getById(request.getAccountGroupId());
            List<AccountGroupAccountRelationship> relationships = relationshipMapper.selectList(
                    new LambdaQueryWrapper<AccountGroupAccountRelationship>()
                            .eq(AccountGroupAccountRelationship::getGroupId, request.getAccountGroupId()));

            List<AdPlan> plans = buildPlans(request, accountGroup, relationships);

            return Result.success(plans, "重新创建广告计划配置成功");
        } catch (Exception e) {
            log.error("重新创建广告计划配置失败", e);
            return Result.fail("重新创建广告计划配置失败: " + e.getMessage());
        }
    }

    private List<AdPlan> buildPlans(UpdateAdPlanConfRequest request, AccountGroup accountGroup,
            List<AccountGroupAccountRelationship> relationships) {
        String dateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String accountGroupName = accountGroup.getGroupName();
        String creativeFileUrls = request.getCreativeFileUrls();
        String creativeFileNames = request.getCreativeFileNames();
        String[] creativeUrlArray = creativeFileUrls.split(",");
        String[] creativeNameArray = creativeFileNames != null ? creativeFileNames.split(",") : new String[0];
        List<AdPlan> plans = new ArrayList<>();
        int i = 0;
        for (AccountGroupAccountRelationship relationship : relationships) {
            Long accountId = relationship.getAccountId();

            String targets = request.getTargets();
            String sites = request.getSites();

            String[] targetArray = targets.split(",");
            String[] siteArray = sites.split(",");
            for (String target : targetArray) {
                for (String site : siteArray) {
                    i++;
                    // 创建广告计划配置
                    // 广告名称：一般是“账户分组名”+“日期时间”+"自增编号"
                    String planName = accountGroupName.trim() + "-" + dateTime + "-" + i;
                    AdPlan adPlan = new AdPlan();
                    adPlan.setAdPlanConfId(request.getId());
                    adPlan.setAccountId(accountId);
                    adPlan.setAdgroupId(0L);
                    adPlan.setAdgroupName(planName);
                    adPlan.setAdType(request.getAdType());
                    adPlan.setTarget(target);
                    adPlan.setSite(site);
                    adPlan.setConversionId(request.getConversionId());
                    adPlan.setDramaId(request.getDramaId());
                    adPlan.setBidAmount(request.getBidAmount());
                    adPlan.setWxCorpid(request.getWxCorpid());
                    plans.add(adPlan);
                    List<AdPlanCreative> adPlanCreatives = new ArrayList<>();
                    adPlan.setAdCreatives(adPlanCreatives);
                    int j = 0;
                    for (String creativeUrl : creativeUrlArray) {
                        String fileName = (j < creativeNameArray.length && creativeNameArray[j] != null
                                && !creativeNameArray[j].isEmpty())
                                        ? creativeNameArray[j]
                                        : creativeUrl.substring(creativeUrl.lastIndexOf("/") + 1);
                        String creativeName = accountGroupName.trim() + "-" + dateTime + "-" + j + "-" + fileName;
                        AdPlanCreative adPlanCreative = new AdPlanCreative();
                        adPlanCreative.setCreativeFileUrl(creativeUrl);
                        adPlanCreative.setCreativeId(0L);
                        adPlanCreative.setCreativeName(creativeName);
                        adPlanCreative.setCreativeText(request.getCreativeText());
                        adPlanCreative.setImageId(0L);
                        adPlanCreative.setBrandImageId(0L);
                        adPlanCreative.setBrandName(request.getBrandName());
                        adPlanCreative.setBrandImageUrl(request.getBrandImageUrl());
                        adPlanCreative.setButtonText(request.getButtonText());
                        adPlanCreative.setPageIds(request.getPageIds());
                        adPlanCreatives.add(adPlanCreative);
                        j++;
                    }
                }
            }
        }
        return plans;
    }

    @PostMapping("/generate-plan")
    public Result<AdPlanConf> generatePlan(
            @RequestBody UpdateAdPlanConfRequest request,
            @AuthUser SysUser sysUser) {

        SysUser user = sysUserService.getById(sysUser.getId());
        LocalDateTime userTokenExpiresAt = user.getUserTokenExpiresAt();
        if (userTokenExpiresAt == null || userTokenExpiresAt.isBefore(LocalDateTime.now())) {
            return Result.fail("实名认证已过期");
        }

        try {
            AccountGroup accountGroup = accountGroupService.getById(request.getAccountGroupId());
            List<AccountGroupAccountRelationship> relationships = relationshipMapper.selectList(
                    new LambdaQueryWrapper<AccountGroupAccountRelationship>()
                            .eq(AccountGroupAccountRelationship::getGroupId, request.getAccountGroupId()));
            Long confId = request.getId();
            AdPlanConf adPlanConf = new AdPlanConf();
            if (confId == null) {
                BeanUtils.copyProperties(request, adPlanConf);
                adPlanConf.setUserId(sysUser.getId());
                adPlanConf.setJobNumber(sysUser.getJobNumber());
                adPlanConf.setCreator(sysUser.getName());
                confId = adPlanConfService.createAdPlanConf(adPlanConf);
                request.setId(confId);
            } else {
                BeanUtils.copyProperties(request, adPlanConf);
                adPlanConfService.updateAdPlanConf(adPlanConf);
            }
            List<AdPlan> plans = buildPlans(request, accountGroup, relationships);
            for (AdPlan plan : plans) {
                plan.setAdPlanConfId(confId);
            }
            adPlanConfService.generatePlan(plans);

            // 异步对接腾讯接口
            adPlanConfService.asyncTencentInterface(plans);

            return Result.success(adPlanConf, "创建广告计划成功;异步执行接口对接中");
        } catch (Exception e) {
            log.error("创建广告计划失败", e);
            return Result.fail("创建广告计划失败: " + e.getMessage());
        }
    }

    @GetMapping("/reGeneratePlan/{id}")
    public Result<Void> reGeneratePlan(@PathVariable Long id, @AuthUser SysUser sysUser) {
        SysUser user = sysUserService.getById(sysUser.getId());
        LocalDateTime userTokenExpiresAt = user.getUserTokenExpiresAt();
        if (userTokenExpiresAt == null || userTokenExpiresAt.isBefore(LocalDateTime.now())) {
            return Result.fail("实名认证已过期");
        }
        adPlanConfService.asyncReGeneratePlan(id);
        return Result.success("重新生成广告计划执行中");
    }

    /**
     * 创建广告计划配置
     */
    @Operation(summary = "创建广告计划配置", description = "为当前用户创建新的广告计划配置")
    @PostMapping("/create")
    public Result<Long> createAdPlanConf(
            @RequestBody CreateAdPlanConfRequest request,
            @AuthUser SysUser sysUser) {
        try {
            AdPlanConf adPlanConf = new AdPlanConf();
            BeanUtils.copyProperties(request, adPlanConf);
            adPlanConf.setUserId(sysUser.getId());
            adPlanConf.setJobNumber(sysUser.getJobNumber());
            adPlanConf.setCreator(sysUser.getName());

            Long confId = adPlanConfService.createAdPlanConf(adPlanConf);
            return Result.success(confId, "创建广告计划配置成功");
        } catch (Exception e) {
            log.error("创建广告计划配置失败", e);
            return Result.fail("创建广告计划配置失败: " + e.getMessage());
        }
    }

    /**
     * 更新广告计划配置
     */
    @Operation(summary = "更新广告计划配置", description = "更新指定的广告计划配置")
    @PostMapping("/update")
    public Result<Void> updateAdPlanConf(
            @RequestBody UpdateAdPlanConfRequest request,
            @AuthUser SysUser sysUser) {
        try {
            AdPlanConf adPlanConf = new AdPlanConf();
            BeanUtils.copyProperties(request, adPlanConf);
            boolean success = adPlanConfService.updateAdPlanConf(adPlanConf);
            if (success) {
                return Result.success("更新广告计划配置成功");
            } else {
                return Result.fail("广告计划配置不存在或无权限");
            }
        } catch (Exception e) {
            log.error("更新广告计划配置失败", e);
            return Result.fail("更新广告计划配置失败: " + e.getMessage());
        }
    }

    /**
     * 删除广告计划配置
     */
    @Operation(summary = "删除广告计划配置", description = "删除指定的广告计划配置")
    @DeleteMapping("/{confId}")
    public Result<Void> deleteAdPlanConf(
            @Parameter(description = "配置ID", required = true) @PathVariable Long confId,
            @AuthUser SysUser sysUser) {
        try {
            boolean success = adPlanConfService.deleteAdPlanConf(confId, sysUser.getId());
            if (success) {
                return Result.success("删除广告计划配置成功");
            } else {
                return Result.fail("广告计划配置不存在或无权限");
            }
        } catch (Exception e) {
            log.error("删除广告计划配置失败", e);
            return Result.fail("删除广告计划配置失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户的广告计划配置列表（分页）
     */
    @Operation(summary = "获取广告计划配置列表", description = "分页获取当前用户的所有广告计划配置")
    @GetMapping("/list")
    public Result<Page<AdPlanConf>> getAdPlanConfs(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer pageSize,
            @AuthUser SysUser sysUser) {
        try {
            Page<AdPlanConf> page = adPlanConfService.getUserAdPlanConfs(
                    sysUser.getId(), pageNum, pageSize);
            return Result.success(page, "查询成功");
        } catch (Exception e) {
            log.error("查询广告计划配置列表失败", e);
            return Result.fail("查询广告计划配置列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取广告计划配置详情
     */
    @Operation(summary = "获取广告计划配置详情", description = "根据ID获取广告计划配置详细信息")
    @GetMapping("/{confId}")
    public Result<AdPlanConf> getAdPlanConf(
            @Parameter(description = "配置ID", required = true) @PathVariable Long confId,
            @AuthUser SysUser sysUser) {
        try {
            AdPlanConf adPlanConf = adPlanConfService.getAdPlanConfById(confId, sysUser.getId());
            if (adPlanConf != null) {
                return Result.success(adPlanConf, "查询成功");
            } else {
                return Result.fail("广告计划配置不存在或无权限");
            }
        } catch (Exception e) {
            log.error("查询广告计划配置详情失败", e);
            return Result.fail("查询广告计划配置详情失败: " + e.getMessage());
        }
    }
}
