package shop.alien.store.util;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import shop.alien.entity.store.LawyerUser;
import shop.alien.entity.store.LifeUser;
import shop.alien.entity.store.StoreClockIn;
import shop.alien.entity.store.StoreUser;
import shop.alien.entity.store.vo.StoreClockInVo;
import shop.alien.mapper.LawyerUserMapper;
import shop.alien.mapper.LifeUserMapper;
import shop.alien.mapper.StoreUserMapper;
import shop.alien.util.type.PhoneTypeIdResult;
import shop.alien.util.type.TypeUtil;

import java.util.Objects;

/**
 * store_clock_in 打卡人身份工具。
 * <p>
 * 入参：兼容前端 legacy {@code phoneId}（解析为 type+refId）。<br>
 * 库表：查询/新增/修改只使用 {@code phone_user_type} + {@code phone_ref_id}，不读写 {@code phone_id} 列。<br>
 * 响应：由 type+refId 合成 {@code phoneId} 返回给前端。
 * </p>
 */
@Component
@RequiredArgsConstructor
public class StoreClockInIdentityHelper {

    public static final int TYPE_USER = 1;
    public static final int TYPE_STORE = 2;
    public static final int TYPE_LAWYER = 3;

    private final TypeUtil typeUtil;
    private final LifeUserMapper lifeUserMapper;
    private final StoreUserMapper storeUserMapper;
    private final LawyerUserMapper lawyerUserMapper;

    public static final class PublisherScope {
        private final String legacyPhoneId;
        private final Integer phoneUserType;
        private final Integer phoneRefId;

        public PublisherScope(String legacyPhoneId, Integer phoneUserType, Integer phoneRefId) {
            this.legacyPhoneId = legacyPhoneId;
            this.phoneUserType = phoneUserType;
            this.phoneRefId = phoneRefId;
        }

        public String getLegacyPhoneId() {
            return legacyPhoneId;
        }

        public Integer getPhoneUserType() {
            return phoneUserType;
        }

        public Integer getPhoneRefId() {
            return phoneRefId;
        }

        public boolean hasTypeRef() {
            return phoneUserType != null && phoneRefId != null;
        }
    }

    /** 将前端传入的 legacy phoneId 解析为 type+refId（仅入参侧兼容）。 */
    public PublisherScope resolveFromPhoneId(String phoneId) {
        if (!StringUtils.hasText(phoneId)) {
            return new PublisherScope(null, null, null);
        }
        String trimmed = phoneId.trim();
        if (!typeUtil.containsUnderscore(trimmed)) {
            return new PublisherScope(trimmed, null, null);
        }
        PhoneTypeIdResult resolved = typeUtil.resolveTypeAndId(trimmed);
        if (resolved == null) {
            return new PublisherScope(trimmed, null, null);
        }
        return new PublisherScope(trimmed, resolved.getType(), resolved.getId());
    }

    public PublisherScope fromLifeUserId(Integer lifeUserId) {
        if (lifeUserId == null) {
            return new PublisherScope(null, null, null);
        }
        LifeUser user = lifeUserMapper.selectById(lifeUserId);
        if (user != null && StringUtils.hasText(user.getUserPhone())) {
            return new PublisherScope("user_" + user.getUserPhone(), TYPE_USER, lifeUserId);
        }
        return new PublisherScope(String.valueOf(lifeUserId), TYPE_USER, lifeUserId);
    }

    /** 从库表记录解析打卡人（仅认 phone_user_type + phone_ref_id）。 */
    public PublisherScope resolveFromClockIn(StoreClockIn clockIn) {
        if (clockIn == null
                || clockIn.getPhoneUserType() == null
                || clockIn.getPhoneRefId() == null) {
            return new PublisherScope(null, null, null);
        }
        String legacy = buildLegacyPhoneId(clockIn.getPhoneUserType(), clockIn.getPhoneRefId());
        return new PublisherScope(legacy, clockIn.getPhoneUserType(), clockIn.getPhoneRefId());
    }

    /** 写入前：由前端 phoneId 或显式 type+refId 填充新字段，不落库 phone_id。 */
    public void normalizePublisherFields(StoreClockIn clockIn) {
        if (clockIn == null) {
            return;
        }
        if (clockIn.getPhoneUserType() == null || clockIn.getPhoneRefId() == null) {
            if (StringUtils.hasText(clockIn.getPhoneId())) {
                PhoneTypeIdResult resolved = typeUtil.resolveTypeAndId(clockIn.getPhoneId().trim());
                if (resolved != null) {
                    clockIn.setPhoneUserType(resolved.getType());
                    clockIn.setPhoneRefId(resolved.getId());
                }
            }
        }
        clockIn.setPhoneId(null);
    }

    public void applyPublisherFilter(LambdaQueryWrapper<StoreClockIn> wrapper, PublisherScope scope) {
        if (wrapper == null || scope == null || !scope.hasTypeRef()) {
            return;
        }
        wrapper.eq(StoreClockIn::getPhoneUserType, scope.getPhoneUserType())
                .eq(StoreClockIn::getPhoneRefId, scope.getPhoneRefId());
    }

    public void applyPublisherFilter(QueryWrapper<StoreClockIn> wrapper, PublisherScope scope) {
        applyPublisherFilter(wrapper, scope, null);
    }

    public void applyPublisherFilter(QueryWrapper<StoreClockIn> wrapper, PublisherScope scope, String tableAlias) {
        if (wrapper == null || scope == null || !scope.hasTypeRef()) {
            return;
        }
        String colPrefix = StringUtils.hasText(tableAlias) ? tableAlias + "." : "";
        wrapper.eq(colPrefix + "phone_user_type", scope.getPhoneUserType())
                .eq(colPrefix + "phone_ref_id", scope.getPhoneRefId());
    }

    /** 与 life_fans 等仍使用 legacy 字符串的模块比对。 */
    public String resolveComparablePhoneId(StoreClockIn clockIn) {
        PublisherScope scope = resolveFromClockIn(clockIn);
        if (scope.hasTypeRef()) {
            String legacy = buildLegacyPhoneId(scope.getPhoneUserType(), scope.getPhoneRefId());
            if (legacy != null) {
                return legacy;
            }
        }
        return clockIn != null ? clockIn.getPhoneId() : null;
    }

    public String resolveComparablePhoneId(StoreClockInVo vo) {
        if (vo == null) {
            return null;
        }
        if (vo.getPhoneUserType() != null && vo.getPhoneRefId() != null) {
            String legacy = buildLegacyPhoneId(vo.getPhoneUserType(), vo.getPhoneRefId());
            if (legacy != null) {
                return legacy;
            }
        }
        if (StringUtils.hasText(vo.getPhoneId())) {
            return vo.getPhoneId();
        }
        return resolveComparablePhoneId(copyToEntity(vo));
    }

    public String buildLegacyPhoneId(Integer phoneUserType, Integer phoneRefId) {
        if (phoneUserType == null || phoneRefId == null) {
            return null;
        }
        switch (phoneUserType) {
            case TYPE_USER: {
                LifeUser user = lifeUserMapper.selectById(phoneRefId);
                return user != null && StringUtils.hasText(user.getUserPhone())
                        ? "user_" + user.getUserPhone() : null;
            }
            case TYPE_STORE: {
                StoreUser storeUser = storeUserMapper.selectById(phoneRefId);
                return storeUser != null && StringUtils.hasText(storeUser.getPhone())
                        ? "store_" + storeUser.getPhone() : null;
            }
            case TYPE_LAWYER: {
                LawyerUser lawyerUser = lawyerUserMapper.selectById(phoneRefId);
                return lawyerUser != null && StringUtils.hasText(lawyerUser.getPhone())
                        ? "lawyer_" + lawyerUser.getPhone() : null;
            }
            default:
                return null;
        }
    }

    /** 响应侧：由 type+refId 合成 phoneId，不读库表 phone_id。 */
    public void ensureVoLegacyPhoneId(StoreClockInVo vo) {
        if (vo == null || vo.getPhoneUserType() == null || vo.getPhoneRefId() == null) {
            return;
        }
        String legacy = buildLegacyPhoneId(vo.getPhoneUserType(), vo.getPhoneRefId());
        if (legacy != null) {
            vo.setPhoneId(legacy);
        }
    }

    public void ensureEntityLegacyPhoneId(StoreClockIn clockIn) {
        if (clockIn == null || clockIn.getPhoneUserType() == null || clockIn.getPhoneRefId() == null) {
            return;
        }
        String legacy = buildLegacyPhoneId(clockIn.getPhoneUserType(), clockIn.getPhoneRefId());
        if (legacy != null) {
            clockIn.setPhoneId(legacy);
        }
    }

    public boolean isSamePublisher(StoreClockIn clockIn, PublisherScope scope) {
        if (clockIn == null || scope == null || !scope.hasTypeRef()) {
            return false;
        }
        PublisherScope itemScope = resolveFromClockIn(clockIn);
        return itemScope.hasTypeRef()
                && Objects.equals(scope.getPhoneUserType(), itemScope.getPhoneUserType())
                && Objects.equals(scope.getPhoneRefId(), itemScope.getPhoneRefId());
    }

    private StoreClockIn copyToEntity(StoreClockInVo vo) {
        StoreClockIn entity = new StoreClockIn();
        entity.setPhoneUserType(vo.getPhoneUserType());
        entity.setPhoneRefId(vo.getPhoneRefId());
        entity.setPhoneId(vo.getPhoneId());
        return entity;
    }
}
