import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { PlatformConfig } from '@/entities/platform-config.entity';

export interface BankCard {
  id: number;
  cardName: string;
  bankName: string;
  bankAccount: string;
  accountName: string;
  isDefault: boolean;
  status: 'active' | 'inactive';
  remark?: string;
  createdAt: string;
  updatedAt: string;
}

@Injectable()
export class BankCardService {
  constructor(
    @InjectRepository(PlatformConfig)
    private configRepo: Repository<PlatformConfig>,
    private dataSource: DataSource,
  ) {}

  private readonly CONFIG_KEY = 'platform_bank_cards';

  async getBankCards(): Promise<BankCard[]> {
    const config = await this.configRepo.findOne({
      where: { configKey: this.CONFIG_KEY },
    });

    if (!config) {
      return [];
    }

    try {
      const cards = JSON.parse(config.configValue);
      return Array.isArray(cards) ? cards : [];
    } catch (error) {
      return [];
    }
  }

  async getBankCardById(id: number): Promise<BankCard | null> {
    const cards = await this.getBankCards();
    return cards.find(card => card.id === id) || null;
  }

  async createBankCard(data: {
    cardName: string;
    bankName: string;
    bankAccount: string;
    accountName: string;
    isDefault?: boolean;
    remark?: string;
  }): Promise<BankCard> {
    const cards = await this.getBankCards();

    const newCard: BankCard = {
      id: cards.length > 0 ? Math.max(...cards.map(c => c.id)) + 1 : 1,
      cardName: data.cardName,
      bankName: data.bankName,
      bankAccount: data.bankAccount,
      accountName: data.accountName,
      isDefault: data.isDefault || false,
      status: 'active',
      remark: data.remark,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };

    if (newCard.isDefault) {
      cards.forEach(card => {
        card.isDefault = false;
      });
    }

    cards.push(newCard);

    await this.saveBankCards(cards);

    return newCard;
  }

  async updateBankCard(
    id: number,
    data: {
      cardName?: string;
      bankName?: string;
      bankAccount?: string;
      accountName?: string;
      isDefault?: boolean;
      remark?: string;
    },
  ): Promise<BankCard> {
    const cards = await this.getBankCards();
    const cardIndex = cards.findIndex(card => card.id === id);

    if (cardIndex === -1) {
      throw new NotFoundException('银行卡不存在');
    }

    const card = cards[cardIndex];

    if (data.cardName !== undefined) card.cardName = data.cardName;
    if (data.bankName !== undefined) card.bankName = data.bankName;
    if (data.bankAccount !== undefined) card.bankAccount = data.bankAccount;
    if (data.accountName !== undefined) card.accountName = data.accountName;
    if (data.remark !== undefined) card.remark = data.remark;

    if (data.isDefault !== undefined && data.isDefault) {
      cards.forEach(c => {
        c.isDefault = false;
      });
      card.isDefault = true;
    }

    card.updatedAt = new Date().toISOString();

    await this.saveBankCards(cards);

    return card;
  }

  async deleteBankCard(id: number): Promise<void> {
    const cards = await this.getBankCards();
    const cardIndex = cards.findIndex(card => card.id === id);

    if (cardIndex === -1) {
      throw new NotFoundException('银行卡不存在');
    }

    const deletedCard = cards[cardIndex];

    if (deletedCard.isDefault && cards.length > 1) {
      throw new BadRequestException('不能删除默认银行卡，请先设置其他银行卡为默认');
    }

    cards.splice(cardIndex, 1);

    await this.saveBankCards(cards);
  }

  async getDefaultBankCard(): Promise<BankCard | null> {
    const cards = await this.getBankCards();
    return cards.find(card => card.isDefault && card.status === 'active') || null;
  }

  private async saveBankCards(cards: BankCard[]): Promise<void> {
    const config = await this.configRepo.findOne({
      where: { configKey: this.CONFIG_KEY },
    });

    const value = JSON.stringify(cards);

    if (config) {
      config.configValue = value;
      config.updatedAt = new Date();
      await this.configRepo.save(config);
    } else {
      const newConfig = this.configRepo.create({
        configKey: this.CONFIG_KEY,
        configValue: value,
        description: '平台银行卡配置',
      });
      await this.configRepo.save(newConfig);
    }
  }
}
