/**
 * Shop Manager Module
 * Handles in-game store items and in-app purchase items.
 * Ported from Python shop/shop_manager.py
 */

import { Player } from '../../models/Player.js';
import { Person } from '../../models/Person.js';

// ============================================================================
// Types
// ============================================================================

export interface StoreItem {
  id: string;
  name: string;
  image: string | null;
  price: number;
  description: string;
  prestigeBoost: number;
  energyBoost: number;
  /**
   * Recurring weekly upkeep charged for owning this (prestige) item. Derived
   * from prestigeBoost so flashier purchases cost more to maintain, creating an
   * ongoing money sink that the finance system charges every week.
   */
  weeklyUpkeep: number;
  /**
   * Minimum character prestige required to purchase this item. Exclusive,
   * status-symbol items are locked until the player has built a reputation,
   * giving prestige a mechanical payoff beyond cosmetics. 0/undefined = open
   * to all. Enforced in purchaseItem().
   */
  minPrestige: number;
  /** True for items gated behind a prestige requirement (client badge). */
  exclusive: boolean;
}

/**
 * Per-prestige-point weekly upkeep for owned lifestyle items. A Sports Car
 * (prestige 50) costs ~$50/wk to maintain; a Designer Sunglasses (prestige 5)
 * ~$5/wk. Consumable energy items (prestigeBoost 0) carry no upkeep.
 */
export const UPKEEP_PER_PRESTIGE = 1;

export interface InAppPurchaseItem {
  id: string;
  name: string;
  price: number;
  description: string;
  diamonds: number;
  image: string;
}

export interface PurchaseResult {
  success: boolean;
  message: string;
  item?: StoreItem;
}

// ============================================================================
// Store Item Factory
// ============================================================================

/** Stable id from display name so catalog ids match across getStoreItems() calls. */
function storeItemSlug(name: string): string {
  return name
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '');
}

/**
 * Create a new store item
 */
export function createStoreItem(
  name: string,
  price: number,
  description: string,
  prestigeBoost: number,
  image: string | null = null,
  energyBoost: number = 0,
  minPrestige: number = 0
): StoreItem {
  return {
    id: storeItemSlug(name),
    name,
    image,
    price,
    description,
    prestigeBoost,
    energyBoost,
    // Prestige (permanent) items carry recurring upkeep; consumables don't.
    weeklyUpkeep: prestigeBoost > 0 ? prestigeBoost * UPKEEP_PER_PRESTIGE : 0,
    minPrestige,
    exclusive: minPrestige > 0,
  };
}

// ============================================================================
// Store Items Catalog
// ============================================================================

let cachedStoreItems: StoreItem[] | null = null;

function buildStoreItemsCatalog(): StoreItem[] {
  return [
    createStoreItem(
      'Case of Energy Drinks',
      100,
      'Gives you a +20 energy boost',
      0,
      'https://media.discordapp.net/attachments/1106614533402931284/1187548155630329937/craig_vg_cozy_cartoon-style_image_of_a_pack_of_energy_drinks._T_bee4a32e-9d74-422c-813a-a20c1a198c5f.png?ex=66060767&is=65f39267&hm=afa75cf6bc2477fed66536b28371988a1e29dd9d835d0fc31a9834bc83980319&=&format=png&quality=lossless&width=526&height=526',
      20
    ),
    createStoreItem(
      'Sports Car',
      50000,
      'A shiny new sports car to show off.',
      50,
      'https://v3b.fal.media/files/b/zebra/qZXW3UgLfqPzkOKvkJeOt_output.png'
    ),
    createStoreItem(
      'Luxury Phone',
      20000,
      'A state-of-the-art smartphone with the latest technology.',
      20
    ),
    createStoreItem(
      'Designer Suit',
      7000,
      'A designer suit to make a great impression.',
      15,
      'https://v3b.fal.media/files/b/penguin/rt2iZVcC_9kSe8B29V3ak_output.png'
    ),
    createStoreItem(
      'Luxury Watch',
      10000,
      'A timeless piece of fine craftsmanship.',
      25
    ),
    createStoreItem(
      'High-End Laptop',
      25000,
      'A high-performance laptop for both work and play.',
      35
    ),
    createStoreItem(
      'Artisan Coffee Machine',
      4000,
      'Make perfect coffee every time.',
      10,
      'https://v3b.fal.media/files/b/monkey/G9qa80OkcyEnDjWjKm8q4_output.png'
    ),
    createStoreItem(
      'Luxury Yacht',
      200000,
      'A personal luxury yacht for parties and more.',
      100
    ),
    createStoreItem(
      'Private Jet',
      300000,
      'Travel in style and comfort with a private jet.',
      150
    ),
    createStoreItem(
      'Designer Handbag',
      5000,
      'A handbag from a famous designer.',
      10,
      'https://v3b.fal.media/files/b/panda/i4G7JcMyYH8sP1qCaSmaZ_output.png'
    ),
    createStoreItem(
      'Diamond Ring',
      8000,
      'A dazzling ring with a large diamond.',
      20,
      'https://v3b.fal.media/files/b/tiger/XjFTzmkaa0ILumrKOcTK3_output.png'
    ),
    createStoreItem(
      'Personal Island',
      500000,
      'Your very own island paradise.',
      200
    ),
    createStoreItem(
      'Luxury Villa',
      150000,
      'A luxurious villa in a prime location.',
      75
    ),
    createStoreItem(
      'Exotic Pet',
      15000,
      'A unique pet to accompany your journey.',
      30
    ),
    createStoreItem(
      'Gourmet Chef',
      12000,
      'Hire a gourmet chef to cook your meals.',
      25
    ),
    createStoreItem(
      'Famous Painting',
      40000,
      'An original painting from a famous artist.',
      40
    ),
    createStoreItem(
      'Rare Wine',
      5000,
      'A bottle of rare and vintage wine.',
      10,
      'https://v3b.fal.media/files/b/koala/OePvHz6E3K8XTRtrjzQt7_output.png'
    ),
    createStoreItem(
      'Limited Edition Sneakers',
      3000,
      'Limited edition sneakers from a high-end brand.',
      8,
      'https://v3b.fal.media/files/b/panda/_SWcVFQ-SqyLHSQuU_Uq__output.png'
    ),
    createStoreItem(
      'Luxury Skincare Set',
      2000,
      'A luxury skincare set for ultimate pampering.',
      7
    ),
    createStoreItem(
      'Concert Tickets',
      2500,
      'Tickets to see your favorite artist live.',
      8
    ),
    createStoreItem(
      'Custom-Made Dress',
      7000,
      'A custom-made dress from a renowned designer.',
      15
    ),
    createStoreItem(
      'High-End Stereo System',
      8000,
      'A high-end stereo system for the best audio experience.',
      20
    ),
    createStoreItem(
      'Designer Sunglasses',
      1500,
      'Stylish sunglasses from a famous brand.',
      5,
      'https://v3b.fal.media/files/b/lion/vcw1faj-Iwe3KsBtkKi09_output.png'
    ),
    createStoreItem(
      'Five Star Vacation',
      10000,
      'An all-inclusive vacation at a five-star resort.',
      25
    ),
    createStoreItem(
      'Fitness Membership',
      3000,
      'Membership to a high-end fitness club.',
      10
    ),
    createStoreItem(
      'Gourmet Kitchen Set',
      15000,
      'A set of top-notch kitchen appliances.',
      25
    ),
    createStoreItem(
      'Home Theatre System',
      20000,
      'Turn your home into a personal cinema.',
      30
    ),
    createStoreItem(
      'Vintage Guitar',
      10000,
      'A beautiful vintage guitar for music lovers.',
      20
    ),
    createStoreItem(
      'Designer Furniture Set',
      30000,
      'Furnish your home with a unique designer touch.',
      35
    ),
    createStoreItem(
      'Luxury Fragrance',
      5000,
      'A signature scent from a high-end brand.',
      10,
      'https://v3b.fal.media/files/b/rabbit/KLB-SKDI3SEWLV6vnRpT-_output.png'
    ),
    createStoreItem(
      'Antique Chess Set',
      3000,
      'An antique chess set for intellectual stimulation.',
      7
    ),
    createStoreItem(
      'Rare Book Collection',
      7000,
      'A collection of rare and valuable books.',
      15
    ),
    createStoreItem(
      'Upscale Pet House',
      4000,
      'A deluxe house for your pet.',
      10
    ),
    createStoreItem(
      'Orchard Garden',
      10000,
      'Grow your own fruit in your backyard.',
      20
    ),
    createStoreItem(
      'Private Helicopter',
      100000,
      'Get to your destination in no time with a private helicopter.',
      75
    ),
    createStoreItem(
      'Gold-Plated Pool Table',
      12000,
      'A pool table with a golden touch.',
      20
    ),
    createStoreItem(
      'Smart Home System',
      25000,
      'Turn your home into a smart home with the latest technology.',
      30
    ),
    createStoreItem(
      'Rare Comic Collection',
      5000,
      'A collection of rare and vintage comic books.',
      10
    ),
    createStoreItem(
      'Collectors Edition Board Games',
      4000,
      "Collector's edition versions of popular board games.",
      10
    ),
    createStoreItem(
      'Home Recording Studio',
      30000,
      'Create your own music with a home recording studio.',
      35
    ),
    createStoreItem(
      'Advanced Drone',
      8000,
      'An advanced drone for capturing high-quality footage.',
      20
    ),
    createStoreItem(
      'Luxury Hot Tub',
      15000,
      'Relax in style with a luxury hot tub.',
      25
    ),
    createStoreItem(
      'Designer Watch',
      20000,
      'A designer watch that makes a statement.',
      30
    ),
    createStoreItem(
      'Platinum Credit Card',
      10000,
      'A platinum credit card with a high spending limit.',
      20
    ),
    createStoreItem(
      'Personal Robot',
      50000,
      'A personal robot to assist with daily tasks.',
      50
    ),
    createStoreItem(
      'Crystal Chandelier',
      8000,
      'Add a touch of elegance to your home with a crystal chandelier.',
      20
    ),
    createStoreItem(
      'Italian Leather Sofa',
      7000,
      'A luxurious Italian leather sofa for your living room.',
      15
    ),
    createStoreItem(
      'Skydiving Experience',
      3000,
      'Experience the thrill of skydiving.',
      10
    ),
    createStoreItem(
      'Space Travel Ticket',
      100000,
      'Travel to space for an unforgettable experience.',
      100
    ),
    createStoreItem(
      'Virtual Reality System',
      5000,
      'Experience the future of gaming with a virtual reality system.',
      15
    ),

    // ── Prestige-Gated Exclusives ──────────────────────────────────────────
    // Status symbols locked behind a prestige requirement. Owning them is a
    // mechanical payoff for the prestige you've accumulated through lifestyle
    // purchases and family legacy. Each is rejected by purchaseItem() unless
    // the character's prestige meets minPrestige.
    createStoreItem(
      'Vintage Supercar Collection',
      750000,
      'A garage of rare supercars reserved for the genuinely renowned.',
      120,
      null,
      0,
      100 // minPrestige
    ),
    createStoreItem(
      'Private Members Club',
      1000000,
      'A lifetime seat at the most exclusive members club in the world.',
      200,
      null,
      0,
      250 // minPrestige
    ),
    createStoreItem(
      'Royal Estate',
      5000000,
      'A historic royal estate that only legends could ever acquire.',
      400,
      null,
      0,
      500 // minPrestige
    ),
  ];
}

/**
 * Get all available store items (stable ids, single cached catalog per process).
 */
export function getStoreItems(): StoreItem[] {
  if (!cachedStoreItems) {
    cachedStoreItems = buildStoreItemsCatalog();
  }
  return cachedStoreItems;
}

/** Reset catalog cache (tests only). */
export function resetStoreItemsCacheForTests(): void {
  cachedStoreItems = null;
}

// ============================================================================
// Store Purchase Logic
// ============================================================================

/**
 * Calculate peak energy for a character (simple implementation)
 */
function getPeakEnergy(person: Person): void {
  // Peak energy is typically the maximum energy a character can have
  // This is a simplified version - actual implementation may vary
  const peakEnergy = 100; // Default peak energy
  if (person.energy > peakEnergy) {
    person.energy = peakEnergy;
  }
}

/**
 * Process purchase of a store item
 */
export function purchaseItem(player: Player, itemId: string): PurchaseResult {
  // Find item in store catalog
  const storeItems = getStoreItems();
  const item = storeItems.find((i: StoreItem) => i.id === itemId);

  if (!item) {
    return {
      success: false,
      message: 'Item not found',
    };
  }

  // Prestige gate: exclusive status items require a minimum prestige to buy.
  if (item.minPrestige > 0 && (player.c.prestige ?? 0) < item.minPrestige) {
    return {
      success: false,
      message: `${item.name} requires ${item.minPrestige} prestige to purchase (you have ${player.c.prestige ?? 0}).`,
    };
  }

  if (player.c.money < item.price) {
    return {
      success: false,
      message: 'Insufficient funds',
    };
  }

  // Deduct money
  player.c.money -= item.price;

  // Apply benefits
  player.c.prestige = (player.c.prestige || 0) + item.prestigeBoost;

  if (item.energyBoost > 0) {
    // Energy boost item - apply energy, capped at the 100 ceiling so a boost
    // can never push a character above max energy.
    player.c.energy = Math.min(100, (player.c.energy || 0) + item.energyBoost);
    getPeakEnergy(player.c);
  } else {
    // Permanent item - add to inventory, carrying its recurring weekly upkeep so
    // the finance system charges an ongoing lifestyle cost for owning it.
    if (!player.c.items) {
      player.c.items = [];
    }
    player.c.items.push({
      id: item.id,
      name: item.name,
      type: 'prestige',
      value: item.price,
      weeklyUpkeep: item.weeklyUpkeep,
    });
  }

  player.messageQueue.push(
    `Purchased ${item.name} for $${item.price.toLocaleString()}`
  );

  return {
    success: true,
    message: `Successfully purchased ${item.name}`,
    item,
  };
}

// ============================================================================
// In-App Purchase Items
// ============================================================================

/**
 * Create an in-app purchase item
 */
export function createInAppPurchaseItem(
  id: string,
  name: string,
  price: number,
  description: string,
  diamonds: number,
  image: string = 'https://v3b.fal.media/files/b/tiger/Jxcl60OfljvE7E8kmrsF1_output.png'
): InAppPurchaseItem {
  return {
    id,
    name,
    price,
    description,
    diamonds,
    image,
  };
}

/**
 * Get all in-app purchase items
 */
export function getInAppPurchaseItems(): InAppPurchaseItem[] {
  return [
    createInAppPurchaseItem(
      'item1',
      'Diamond Pack 1',
      0.99,
      'Get 100 diamonds!',
      100
    ),
    createInAppPurchaseItem(
      'item2',
      'Diamond Pack 2',
      1.99,
      'Get 210 diamonds!',
      210
    ),
    createInAppPurchaseItem(
      'item3',
      'Diamond Pack 3',
      2.99,
      'Get 330 diamonds!',
      330
    ),
    createInAppPurchaseItem(
      'item4',
      'Diamond Pack 4',
      3.99,
      'Get 460 diamonds!',
      460
    ),
    createInAppPurchaseItem(
      'item5',
      'Diamond Pack 5',
      4.99,
      'Get 600 diamonds!',
      600
    ),
  ];
}

/**
 * Process an in-app purchase
 * Note: Actual payment processing happens elsewhere; this only awards the diamonds
 */
export function purchaseInAppItem(player: Player, itemId: string): boolean {
  const items = getInAppPurchaseItems();
  const item = items.find((i) => i.id === itemId);

  if (item) {
    player.c.diamonds = (player.c.diamonds || 0) + item.diamonds;
    player.messageQueue.push(`Received ${item.diamonds} diamonds!`);
    return true;
  }

  return false;
}

// ============================================================================
// Export
// ============================================================================

export const shopManager = {
  createStoreItem,
  getStoreItems,
  purchaseItem,
  createInAppPurchaseItem,
  getInAppPurchaseItems,
  purchaseInAppItem,
};
