package com.rj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rj.common.LbThirdIntegrationConstants;
import com.rj.dto.LbThirdIntegrationCredentialUpdateRequest;
import com.rj.dto.hxr.HxrAdminOrderApiContext;
import com.rj.dto.hxr.HxrAdminUserApiContext;
import com.rj.dto.hxr.HxrGoodsApiContext;
import com.rj.entity.LbThirdIntegrationConfig;
import com.rj.mapper.LbThirdIntegrationConfigMapper;
import com.rj.service.ILbThirdIntegrationConfigService;
import com.rj.util.LbThirdIntegrationConfigUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

/**
 * 租户第三方集成配置服务实现
 */
@Service
public class LbThirdIntegrationConfigServiceImpl
        extends ServiceImpl<LbThirdIntegrationConfigMapper, LbThirdIntegrationConfig>
        implements ILbThirdIntegrationConfigService {

    @Override
    public Map<String, Object> add(LbThirdIntegrationConfig entity) {
        Map<String, Object> result = new HashMap<>();
        try {
            String validationError = validateRequiredForAdd(entity);
            if (validationError != null) {
                result.put("success", false);
                result.put("message", validationError);
                return result;
            }

            String tenantId = entity.getTenantId().trim();
            if (this.count(new LambdaQueryWrapper<LbThirdIntegrationConfig>()
                    .eq(LbThirdIntegrationConfig::getTenantId, tenantId)) > 0) {
                result.put("success", false);
                result.put("message", "该租户已存在集成配置，不能重复添加");
                return result;
            }

            applyDefaults(entity);
            entity.setTenantId(tenantId);
            entity.setId(UUID.randomUUID().toString());
            LocalDateTime now = LocalDateTime.now();
            entity.setCreateTime(now);
            entity.setUpdateTime(now);

            if (entity.getCredentialVersion() == null) {
                entity.setCredentialVersion(1);
            }

            boolean ok = this.save(entity);
            result.put("success", ok);
            result.put("message", ok ? "添加成功" : "添加失败");
            if (ok) {
                result.put("data", maskForResponse(this.getById(entity.getId())));
            }
            return result;
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "添加异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Map<String, Object> update(LbThirdIntegrationConfig entity) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (!StringUtils.hasText(entity.getId())) {
                result.put("success", false);
                result.put("message", "ID不能为空");
                return result;
            }

            LbThirdIntegrationConfig existing = this.getById(entity.getId().trim());
            if (existing == null) {
                result.put("success", false);
                result.put("message", "记录不存在");
                return result;
            }

            if (StringUtils.hasText(entity.getTenantId())
                    && !entity.getTenantId().trim().equals(existing.getTenantId())) {
                String newTenantId = entity.getTenantId().trim();
                long dup = this.count(new LambdaQueryWrapper<LbThirdIntegrationConfig>()
                        .eq(LbThirdIntegrationConfig::getTenantId, newTenantId)
                        .ne(LbThirdIntegrationConfig::getId, existing.getId()));
                if (dup > 0) {
                    result.put("success", false);
                    result.put("message", "目标租户已存在集成配置");
                    return result;
                }
            }

            boolean credentialUpdated = applyCredentials(entity, existing);
            if (credentialUpdated) {
                int version = existing.getCredentialVersion() == null ? 1 : existing.getCredentialVersion();
                entity.setCredentialVersion(version + 1);
            }

            entity.setUpdateTime(LocalDateTime.now());
            boolean ok = this.updateById(entity);
            result.put("success", ok);
            result.put("message", ok ? "更新成功" : "更新失败");
            if (ok) {
                result.put("data", maskForResponse(this.getById(entity.getId())));
            }
            return result;
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "更新异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Map<String, Object> deleteById(String id) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (!StringUtils.hasText(id)) {
                result.put("success", false);
                result.put("message", "ID不能为空");
                return result;
            }
            boolean ok = this.removeById(id.trim());
            result.put("success", ok);
            result.put("message", ok ? "删除成功" : "删除失败");
            return result;
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "删除异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Map<String, Object> pageQuery(Integer current,
                                         Integer size,
                                         String tenantId,
                                         String providerCode,
                                         Integer enabled) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (current == null || current < 1) {
                current = 1;
            }
            if (size == null || size < 1) {
                size = 10;
            }

            LambdaQueryWrapper<LbThirdIntegrationConfig> q = new LambdaQueryWrapper<>();
            if (StringUtils.hasText(tenantId)) {
                q.eq(LbThirdIntegrationConfig::getTenantId, tenantId.trim());
            }
            if (StringUtils.hasText(providerCode)) {
                q.eq(LbThirdIntegrationConfig::getProviderCode, providerCode.trim());
            }
            if (enabled != null) {
                q.eq(LbThirdIntegrationConfig::getEnabled, enabled);
            }
            q.orderByDesc(LbThirdIntegrationConfig::getUpdateTime)
                    .orderByDesc(LbThirdIntegrationConfig::getCreateTime);

            Page<LbThirdIntegrationConfig> page = this.page(new Page<>(current, size), q);
            List<LbThirdIntegrationConfig> records = page.getRecords().stream()
                    .map(this::maskForResponse)
                    .toList();

            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", records);
            result.put("total", page.getTotal());
            result.put("current", page.getCurrent());
            result.put("size", page.getSize());
            result.put("pages", page.getPages());
            return result;
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "查询异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Map<String, Object> getDetailById(String id) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (!StringUtils.hasText(id)) {
                result.put("success", false);
                result.put("message", "ID不能为空");
                return result;
            }
            LbThirdIntegrationConfig data = this.getById(id.trim());
            if (data == null) {
                result.put("success", false);
                result.put("message", "记录不存在");
                return result;
            }
            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", maskForResponse(data));
            return result;
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "查询异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Map<String, Object> getCredentialStatusByTenantId(String tenantId) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (!StringUtils.hasText(tenantId)) {
                result.put("success", false);
                result.put("message", "tenantId不能为空");
                return result;
            }
            LbThirdIntegrationConfig config = getByTenantIdOrNull(tenantId.trim());
            if (config == null) {
                result.put("success", false);
                result.put("message", "该租户未配置第三方集成");
                return result;
            }
            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", buildCredentialStatus(config, true));
            return result;
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "查询异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Map<String, Object> updateCredentialByTenantId(
            String tenantId, LbThirdIntegrationCredentialUpdateRequest request) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (!StringUtils.hasText(tenantId)) {
                result.put("success", false);
                result.put("message", "tenantId不能为空");
                return result;
            }
            if (request == null) {
                result.put("success", false);
                result.put("message", "请求体不能为空");
                return result;
            }

            LbThirdIntegrationConfig existing = getByTenantIdOrNull(tenantId.trim());
            if (existing == null) {
                result.put("success", false);
                result.put("message", "该租户未配置第三方集成，请先新增配置");
                return result;
            }

            String validationError = validateCredentialUpdateRequest(request);
            if (validationError != null) {
                result.put("success", false);
                result.put("message", validationError);
                return result;
            }

            LambdaUpdateWrapper<LbThirdIntegrationConfig> uw = new LambdaUpdateWrapper<>();
            uw.eq(LbThirdIntegrationConfig::getId, existing.getId());
            applyCredentialUpdateWrapper(uw, request);

            if (request.getCredentialExpireTime() != null) {
                uw.set(LbThirdIntegrationConfig::getCredentialExpireTime, request.getCredentialExpireTime());
            }
            if (StringUtils.hasText(request.getUpdatedBy())) {
                uw.set(LbThirdIntegrationConfig::getUpdatedBy, request.getUpdatedBy().trim());
            }

            int version = existing.getCredentialVersion() == null ? 1 : existing.getCredentialVersion();
            uw.set(LbThirdIntegrationConfig::getCredentialVersion, version + 1);
            uw.set(LbThirdIntegrationConfig::getUpdateTime, LocalDateTime.now());

            boolean ok = this.update(uw);
            result.put("success", ok);
            result.put("message", ok ? "凭证更新成功" : "凭证更新失败");
            if (ok) {
                LbThirdIntegrationConfig latest = this.getById(existing.getId());
                result.put("data", buildCredentialStatus(latest, true));
            }
            return result;
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "凭证更新异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Optional<HxrGoodsApiContext> resolveGoodsApiContext(String tenantId, String tokenOverride) {
        if (!StringUtils.hasText(tenantId)) {
            return Optional.empty();
        }
        LbThirdIntegrationConfig config = getByTenantIdOrNull(tenantId.trim());
        if (config == null) {
            return Optional.empty();
        }
        if (config.getEnabled() == null || config.getEnabled() != 1) {
            return Optional.empty();
        }

        String token = StringUtils.hasText(tokenOverride)
                ? tokenOverride.trim()
                : config.getGoodsApiToken();
        String appStr = config.getGoodsApiAppStr();
        if (!StringUtils.hasText(token) || !StringUtils.hasText(appStr)) {
            return Optional.empty();
        }

        try {
            return Optional.of(new HxrGoodsApiContext(
                    LbThirdIntegrationConfigUtil.resolveGoodsApiBaseUrl(config),
                    LbThirdIntegrationConfigUtil.resolveGoodsPageLimit(config),
                    LbThirdIntegrationConfigUtil.resolveGoodsApiOrigin(config),
                    LbThirdIntegrationConfigUtil.resolveGoodsApiReferer(config),
                    token.trim(),
                    appStr.trim()));
        } catch (IllegalStateException e) {
            return Optional.empty();
        }
    }

    @Override
    public Optional<HxrAdminUserApiContext> resolveAdminUserApiContext(String tenantId) {
        if (!StringUtils.hasText(tenantId)) {
            return Optional.empty();
        }
        LbThirdIntegrationConfig config = getByTenantIdOrNull(tenantId.trim());
        if (config == null) {
            return Optional.empty();
        }
        if (config.getEnabled() == null || config.getEnabled() != 1) {
            return Optional.empty();
        }

        String cookieHeader = LbThirdIntegrationConfigUtil.resolveCookieHeader(config);
        if (!StringUtils.hasText(cookieHeader)) {
            return Optional.empty();
        }

        try {
            return Optional.of(new HxrAdminUserApiContext(
                    LbThirdIntegrationConfigUtil.resolveUserSelectBaseUrl(config),
                    LbThirdIntegrationConfigUtil.resolveUserPageLimit(config),
                    cookieHeader.trim(),
                    LbThirdIntegrationConfigUtil.resolveUserReferer(config)));
        } catch (IllegalStateException e) {
            return Optional.empty();
        }
    }

    @Override
    public Optional<HxrAdminOrderApiContext> resolveAdminOrderApiContext(String tenantId) {
        if (!StringUtils.hasText(tenantId)) {
            return Optional.empty();
        }
        LbThirdIntegrationConfig config = getByTenantIdOrNull(tenantId.trim());
        if (config == null) {
            return Optional.empty();
        }
        if (config.getEnabled() == null || config.getEnabled() != 1) {
            return Optional.empty();
        }

        String cookieHeader = LbThirdIntegrationConfigUtil.resolveCookieHeader(config);
        if (!StringUtils.hasText(cookieHeader)) {
            return Optional.empty();
        }

        try {
            return Optional.of(new HxrAdminOrderApiContext(
                    LbThirdIntegrationConfigUtil.resolveOrderSelectBaseUrl(config),
                    LbThirdIntegrationConfigUtil.resolveOrderPageLimit(config),
                    cookieHeader.trim(),
                    LbThirdIntegrationConfigUtil.resolveOrderReferer(config)));
        } catch (IllegalStateException e) {
            return Optional.empty();
        }
    }

    private LbThirdIntegrationConfig getByTenantIdOrNull(String tenantId) {
        return this.getOne(new LambdaQueryWrapper<LbThirdIntegrationConfig>()
                .eq(LbThirdIntegrationConfig::getTenantId, tenantId)
                .last("LIMIT 1"));
    }

    private static String validateCredentialUpdateRequest(LbThirdIntegrationCredentialUpdateRequest request) {
        boolean hasUpdate = StringUtils.hasText(request.getCookie())
                || StringUtils.hasText(request.getPhpsid())
                || StringUtils.hasText(request.getGoodsApiToken())
                || StringUtils.hasText(request.getGoodsApiAppStr());
        boolean hasClear = Boolean.TRUE.equals(request.getClearCookie())
                || Boolean.TRUE.equals(request.getClearPhpsid())
                || Boolean.TRUE.equals(request.getClearGoodsApiToken())
                || Boolean.TRUE.equals(request.getClearGoodsApiAppStr());
        if (!hasUpdate && !hasClear) {
            return "请至少提供一项凭证，或指定一项 clear* 清除操作";
        }
        if (Boolean.TRUE.equals(request.getClearCookie()) && StringUtils.hasText(request.getCookie())) {
            return "clearCookie 与 cookie 不能同时传";
        }
        if (Boolean.TRUE.equals(request.getClearPhpsid()) && StringUtils.hasText(request.getPhpsid())) {
            return "clearPhpsid 与 phpsid 不能同时传";
        }
        if (Boolean.TRUE.equals(request.getClearGoodsApiToken()) && StringUtils.hasText(request.getGoodsApiToken())) {
            return "clearGoodsApiToken 与 goodsApiToken 不能同时传";
        }
        if (Boolean.TRUE.equals(request.getClearGoodsApiAppStr()) && StringUtils.hasText(request.getGoodsApiAppStr())) {
            return "clearGoodsApiAppStr 与 goodsApiAppStr 不能同时传";
        }
        return null;
    }

    private void applyCredentialUpdateWrapper(
            LambdaUpdateWrapper<LbThirdIntegrationConfig> uw,
            LbThirdIntegrationCredentialUpdateRequest request) {
        if (Boolean.TRUE.equals(request.getClearCookie())) {
            uw.set(LbThirdIntegrationConfig::getCookie, null);
        } else if (StringUtils.hasText(request.getCookie())) {
            uw.set(LbThirdIntegrationConfig::getCookie, request.getCookie().trim());
        }

        if (Boolean.TRUE.equals(request.getClearPhpsid())) {
            uw.set(LbThirdIntegrationConfig::getPhpsid, null);
        } else if (StringUtils.hasText(request.getPhpsid())) {
            uw.set(LbThirdIntegrationConfig::getPhpsid, request.getPhpsid().trim());
        }

        if (Boolean.TRUE.equals(request.getClearGoodsApiToken())) {
            uw.set(LbThirdIntegrationConfig::getGoodsApiToken, null);
        } else if (StringUtils.hasText(request.getGoodsApiToken())) {
            uw.set(LbThirdIntegrationConfig::getGoodsApiToken, request.getGoodsApiToken().trim());
        }

        if (Boolean.TRUE.equals(request.getClearGoodsApiAppStr())) {
            uw.set(LbThirdIntegrationConfig::getGoodsApiAppStr, null);
        } else if (StringUtils.hasText(request.getGoodsApiAppStr())) {
            uw.set(LbThirdIntegrationConfig::getGoodsApiAppStr, request.getGoodsApiAppStr().trim());
        }
    }

    private Map<String, Object> buildCredentialStatus(LbThirdIntegrationConfig config, boolean includePlaintext) {
        Map<String, Object> data = new HashMap<>();
        data.put("id", config.getId());
        data.put("tenantId", config.getTenantId());
        data.put("providerCode", config.getProviderCode());
        data.put("authType", config.getAuthType());
        data.put("cookieConfigured", isConfigured(config.getCookie()));
        data.put("phpsidConfigured", isConfigured(config.getPhpsid()));
        data.put("goodsApiTokenConfigured", isConfigured(config.getGoodsApiToken()));
        data.put("goodsApiAppStrConfigured", isConfigured(config.getGoodsApiAppStr()));
        data.put("credentialVersion", config.getCredentialVersion());
        data.put("credentialExpireTime", config.getCredentialExpireTime());
        data.put("lastVerifiedTime", config.getLastVerifiedTime());
        data.put("lastVerifiedOk", config.getLastVerifiedOk());
        data.put("updateTime", config.getUpdateTime());
        if (includePlaintext) {
            data.put("cookie", config.getCookie());
            data.put("phpsid", config.getPhpsid());
            data.put("goodsApiToken", config.getGoodsApiToken());
            data.put("goodsApiAppStr", config.getGoodsApiAppStr());
        }
        return data;
    }

    private String validateRequiredForAdd(LbThirdIntegrationConfig entity) {
        if (entity == null) {
            return "请求体不能为空";
        }
        if (!StringUtils.hasText(entity.getTenantId())) {
            return "tenantId不能为空";
        }
        if (!StringUtils.hasText(entity.getAdminBaseUrl())) {
            return "adminBaseUrl不能为空";
        }
        if (!StringUtils.hasText(entity.getWebBaseUrl())) {
            return "webBaseUrl不能为空";
        }
        return null;
    }

    private void applyDefaults(LbThirdIntegrationConfig entity) {
        if (!StringUtils.hasText(entity.getProviderCode())) {
            entity.setProviderCode(LbThirdIntegrationConstants.PROVIDER_HXR_ADMIN);
        }
        if (entity.getEnabled() == null) {
            entity.setEnabled(1);
        }
        if (!StringUtils.hasText(entity.getOrderSelectPath())) {
            entity.setOrderSelectPath(LbThirdIntegrationConstants.DEFAULT_ORDER_SELECT_PATH);
        }
        if (!StringUtils.hasText(entity.getUserSelectPath())) {
            entity.setUserSelectPath(LbThirdIntegrationConstants.DEFAULT_USER_SELECT_PATH);
        }
        if (!StringUtils.hasText(entity.getUserUpdatePath())) {
            entity.setUserUpdatePath(LbThirdIntegrationConstants.DEFAULT_USER_UPDATE_PATH);
        }
        if (!StringUtils.hasText(entity.getGoodsApiPath())) {
            entity.setGoodsApiPath(LbThirdIntegrationConstants.DEFAULT_GOODS_API_PATH);
        }
        if (!StringUtils.hasText(entity.getBuyApiPath())) {
            entity.setBuyApiPath(LbThirdIntegrationConstants.DEFAULT_BUY_API_PATH);
        }
        if (entity.getOrderPageLimit() == null) {
            entity.setOrderPageLimit(LbThirdIntegrationConstants.DEFAULT_ORDER_PAGE_LIMIT);
        }
        if (entity.getUserPageLimit() == null) {
            entity.setUserPageLimit(LbThirdIntegrationConstants.DEFAULT_USER_PAGE_LIMIT);
        }
        if (entity.getGoodsPageLimit() == null) {
            entity.setGoodsPageLimit(LbThirdIntegrationConstants.DEFAULT_GOODS_PAGE_LIMIT);
        }
        if (!StringUtils.hasText(entity.getAuthType())) {
            entity.setAuthType(LbThirdIntegrationConstants.AUTH_COOKIE_PHPSID);
        }
        if (entity.getSyncOrderResellEnabled() == null) {
            entity.setSyncOrderResellEnabled(0);
        }
        if (entity.getSyncOrderUnpaidEnabled() == null) {
            entity.setSyncOrderUnpaidEnabled(0);
        }
        if (entity.getSyncOrderPaidEnabled() == null) {
            entity.setSyncOrderPaidEnabled(0);
        }
        if (entity.getSyncUserEnabled() == null) {
            entity.setSyncUserEnabled(0);
        }
        if (entity.getCredentialVersion() == null) {
            entity.setCredentialVersion(1);
        }
    }

    /**
     * 更新场景下保留未传凭证字段的已有值。
     *
     * @return 是否有任一凭证字段被更新
     */
    private boolean applyCredentials(LbThirdIntegrationConfig entity, LbThirdIntegrationConfig existing) {
        boolean updated = false;

        if (StringUtils.hasText(entity.getCookie())) {
            entity.setCookie(entity.getCookie().trim());
            updated = true;
        } else if (existing != null) {
            entity.setCookie(existing.getCookie());
        }

        if (StringUtils.hasText(entity.getPhpsid())) {
            entity.setPhpsid(entity.getPhpsid().trim());
            updated = true;
        } else if (existing != null) {
            entity.setPhpsid(existing.getPhpsid());
        }

        if (StringUtils.hasText(entity.getGoodsApiToken())) {
            entity.setGoodsApiToken(entity.getGoodsApiToken().trim());
            updated = true;
        } else if (existing != null) {
            entity.setGoodsApiToken(existing.getGoodsApiToken());
        }

        if (StringUtils.hasText(entity.getGoodsApiAppStr())) {
            entity.setGoodsApiAppStr(entity.getGoodsApiAppStr().trim());
            updated = true;
        } else if (existing != null) {
            entity.setGoodsApiAppStr(existing.getGoodsApiAppStr());
        }

        return updated;
    }

    private LbThirdIntegrationConfig maskForResponse(LbThirdIntegrationConfig entity) {
        if (entity == null) {
            return null;
        }
        entity.setCookieConfigured(isConfigured(entity.getCookie()));
        entity.setPhpsidConfigured(isConfigured(entity.getPhpsid()));
        entity.setGoodsApiTokenConfigured(isConfigured(entity.getGoodsApiToken()));
        entity.setGoodsApiAppStrConfigured(isConfigured(entity.getGoodsApiAppStr()));

        entity.setCookie(null);
        entity.setPhpsid(null);
        entity.setGoodsApiToken(null);
        entity.setGoodsApiAppStr(null);
        return entity;
    }

    private static boolean isConfigured(String value) {
        return StringUtils.hasText(value);
    }
}
