import { getDb, creditWallet, debitWallet, writeAuditLog } from './db.ts';
import { eq, and } from 'drizzle-orm';

export type CosmeticType = 'avatar_skin' | 'slot_theme' | 'animation' | 'badge' | 'border' | 'effect';
export type CosmeticRarity = 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary';

export interface Cosmetic {
  id: number;
  name: string;
  description: string;
  type: CosmeticType;
  rarity: CosmeticRarity;
  price: number;
  imageUrl: string;
  previewUrl?: string;
  unlockRequirement?: string; // e.g., "Win 100 games", "Reach VIP Tier 3"
  isLimited: boolean;
  limitedUntil?: Date;
  createdAt: Date;
}

export interface PlayerCosmetic {
  id: number;
  playerId: number;
  cosmeticId: number;
  acquiredAt: Date;
  isActive: boolean;
  activatedAt?: Date;
}

export interface CosmeticShopItem {
  cosmetic: Cosmetic;
  owned: boolean;
  active: boolean;
}

/**
 * Cosmetic Shop Manager
 */
export class CosmeticShopManager {
  private cosmetics: Map<number, Cosmetic> = new Map();
  private playerCosmetics: Map<number, PlayerCosmetic[]> = new Map();

  /**
   * Initialize cosmetics catalog
   */
  async initializeCatalog(): Promise<void> {
    const catalog: Cosmetic[] = [
      // Avatar Skins
      {
        id: 1,
        name: 'Golden Avatar',
        description: 'Shiny golden avatar skin',
        type: 'avatar_skin',
        rarity: 'rare',
        price: 500,
        imageUrl: '/cosmetics/avatar-gold.png',
        isLimited: false,
        createdAt: new Date(),
      },
      {
        id: 2,
        name: 'Diamond Avatar',
        description: 'Sparkling diamond avatar skin',
        type: 'avatar_skin',
        rarity: 'epic',
        price: 1000,
        imageUrl: '/cosmetics/avatar-diamond.png',
        isLimited: false,
        createdAt: new Date(),
      },
      {
        id: 3,
        name: 'Neon Cyberpunk',
        description: 'Futuristic neon avatar',
        type: 'avatar_skin',
        rarity: 'epic',
        price: 1500,
        imageUrl: '/cosmetics/avatar-neon.png',
        isLimited: true,
        limitedUntil: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
        createdAt: new Date(),
      },

      // Slot Themes
      {
        id: 4,
        name: 'Dark Mode Theme',
        description: 'Dark slot machine theme',
        type: 'slot_theme',
        rarity: 'common',
        price: 200,
        imageUrl: '/cosmetics/theme-dark.png',
        isLimited: false,
        createdAt: new Date(),
      },
      {
        id: 5,
        name: 'Ocean Theme',
        description: 'Underwater slot machine theme',
        type: 'slot_theme',
        rarity: 'uncommon',
        price: 400,
        imageUrl: '/cosmetics/theme-ocean.png',
        isLimited: false,
        createdAt: new Date(),
      },
      {
        id: 6,
        name: 'Space Theme',
        description: 'Cosmic slot machine theme',
        type: 'slot_theme',
        rarity: 'rare',
        price: 750,
        imageUrl: '/cosmetics/theme-space.png',
        isLimited: false,
        createdAt: new Date(),
      },

      // Animations
      {
        id: 7,
        name: 'Confetti Explosion',
        description: 'Confetti animation on wins',
        type: 'animation',
        rarity: 'uncommon',
        price: 300,
        imageUrl: '/cosmetics/anim-confetti.png',
        isLimited: false,
        createdAt: new Date(),
      },
      {
        id: 8,
        name: 'Rainbow Spin',
        description: 'Rainbow effect on reel spin',
        type: 'animation',
        rarity: 'rare',
        price: 600,
        imageUrl: '/cosmetics/anim-rainbow.png',
        isLimited: false,
        createdAt: new Date(),
      },

      // Badges
      {
        id: 9,
        name: 'High Roller Badge',
        description: 'Badge for players who bet big',
        type: 'badge',
        rarity: 'rare',
        price: 500,
        imageUrl: '/cosmetics/badge-highroller.png',
        unlockRequirement: 'Wager 50,000 SC',
        isLimited: false,
        createdAt: new Date(),
      },
      {
        id: 10,
        name: 'Jackpot Winner Badge',
        description: 'Badge for jackpot winners',
        type: 'badge',
        rarity: 'legendary',
        price: 0, // Unlocked by winning jackpot
        imageUrl: '/cosmetics/badge-jackpot.png',
        unlockRequirement: 'Win a progressive jackpot',
        isLimited: false,
        createdAt: new Date(),
      },
    ];

    for (const cosmetic of catalog) {
      this.cosmetics.set(cosmetic.id, cosmetic);
    }
  }

  /**
   * Get shop catalog for a player
   */
  async getShopCatalog(playerId: number): Promise<CosmeticShopItem[]> {
    const playerCosmetics = this.playerCosmetics.get(playerId) || [];
    const ownedIds = new Set(playerCosmetics.map((c) => c.cosmeticId));

    return Array.from(this.cosmetics.values()).map((cosmetic) => ({
      cosmetic,
      owned: ownedIds.has(cosmetic.id),
      active: playerCosmetics.some((c) => c.cosmeticId === cosmetic.id && c.isActive),
    }));
  }

  /**
   * Purchase cosmetic
   */
  async purchaseCosmetic(
    playerId: number,
    cosmeticId: number
  ): Promise<{ success: boolean; message: string }> {
    const cosmetic = this.cosmetics.get(cosmeticId);
    if (!cosmetic) {
      return { success: false, message: 'Cosmetic not found' };
    }

    // Check if already owned
    const playerCosmetics = this.playerCosmetics.get(playerId) || [];
    if (playerCosmetics.some((c) => c.cosmeticId === cosmeticId)) {
      return { success: false, message: 'Already owned' };
    }

    // Check if limited time expired
    if (cosmetic.isLimited && cosmetic.limitedUntil && cosmetic.limitedUntil < new Date()) {
      return { success: false, message: 'Limited time offer expired' };
    }

    // Debit wallet
    try {
      await debitWallet(
        playerId,
        'SC',
        cosmetic.price,
        'cosmetic_purchase',
        `Purchased ${cosmetic.name}`,
        String(playerId)
      );
    } catch (error) {
      return { success: false, message: 'Insufficient balance' };
    }

    // Add cosmetic to player
    const playerCosmetic: PlayerCosmetic = {
      id: Math.random(),
      playerId,
      cosmeticId,
      acquiredAt: new Date(),
      isActive: false,
    };

    if (!this.playerCosmetics.has(playerId)) {
      this.playerCosmetics.set(playerId, []);
    }
    this.playerCosmetics.get(playerId)!.push(playerCosmetic);

    // Log purchase
    await writeAuditLog({
      actorId: playerId,
      actorRole: 'user',
      action: 'cosmetic_purchase',
      category: 'shop',
      details: {
        cosmeticId,
        cosmeticName: cosmetic.name,
        price: cosmetic.price,
      },
    });

    return { success: true, message: 'Purchase successful' };
  }

  /**
   * Activate cosmetic
   */
  async activateCosmetic(
    playerId: number,
    cosmeticId: number
  ): Promise<{ success: boolean; message: string }> {
    const playerCosmetics = this.playerCosmetics.get(playerId) || [];
    const cosmetic = playerCosmetics.find((c) => c.cosmeticId === cosmeticId);

    if (!cosmetic) {
      return { success: false, message: 'Cosmetic not owned' };
    }

    // Deactivate others of same type
    const cosmeticType = this.cosmetics.get(cosmeticId)?.type;
    for (const pc of playerCosmetics) {
      if (this.cosmetics.get(pc.cosmeticId)?.type === cosmeticType && pc.id !== cosmetic.id) {
        pc.isActive = false;
      }
    }

    // Activate this cosmetic
    cosmetic.isActive = true;
    cosmetic.activatedAt = new Date();

    return { success: true, message: 'Cosmetic activated' };
  }

  /**
   * Get player's cosmetics
   */
  async getPlayerCosmetics(playerId: number): Promise<PlayerCosmetic[]> {
    return this.playerCosmetics.get(playerId) || [];
  }

  /**
   * Get active cosmetics by type
   */
  async getActiveCosmetics(playerId: number): Promise<Map<CosmeticType, Cosmetic>> {
    const playerCosmetics = this.playerCosmetics.get(playerId) || [];
    const activeCosmetics = new Map<CosmeticType, Cosmetic>();

    for (const pc of playerCosmetics) {
      if (pc.isActive) {
        const cosmetic = this.cosmetics.get(pc.cosmeticId);
        if (cosmetic) {
          activeCosmetics.set(cosmetic.type, cosmetic);
        }
      }
    }

    return activeCosmetics;
  }

  /**
   * Unlock cosmetic (for achievements)
   */
  async unlockCosmetic(playerId: number, cosmeticId: number): Promise<void> {
    const cosmetic = this.cosmetics.get(cosmeticId);
    if (!cosmetic) return;

    // Add cosmetic without charging
    const playerCosmetic: PlayerCosmetic = {
      id: Math.random(),
      playerId,
      cosmeticId,
      acquiredAt: new Date(),
      isActive: false,
    };

    if (!this.playerCosmetics.has(playerId)) {
      this.playerCosmetics.set(playerId, []);
    }
    this.playerCosmetics.get(playerId)!.push(playerCosmetic);

    // Log unlock
    await writeAuditLog({
      actorId: playerId,
      actorRole: 'user',
      action: 'cosmetic_unlocked',
      category: 'achievement',
      details: {
        cosmeticId,
        cosmeticName: cosmetic.name,
      },
    });
  }

  /**
   * Get cosmetic details
   */
  getCosmetic(cosmeticId: number): Cosmetic | undefined {
    return this.cosmetics.get(cosmeticId);
  }

  /**
   * Get cosmetics by type
   */
  getCosmeticsByType(type: CosmeticType): Cosmetic[] {
    return Array.from(this.cosmetics.values()).filter((c) => c.type === type);
  }

  /**
   * Get cosmetics by rarity
   */
  getCosmeticsByRarity(rarity: CosmeticRarity): Cosmetic[] {
    return Array.from(this.cosmetics.values()).filter((c) => c.rarity === rarity);
  }

  /**
   * Get limited time cosmetics
   */
  getLimitedTimeCosmetics(): Cosmetic[] {
    return Array.from(this.cosmetics.values()).filter(
      (c) => c.isLimited && (!c.limitedUntil || c.limitedUntil > new Date())
    );
  }
}

export const cosmeticShopManager = new CosmeticShopManager();
