import type { Character, Proficiency } from '@/shared/types';

// Pathbuilder data structure
interface PathbuilderData {
  build?: {
    name?: string;
    class?: string;
    ancestry?: string;
    heritage?: string;
    background?: string;
    alignment?: string;
    gender?: string;
    age?: string;
    deity?: string;
    sizeName?: string;
    languages?: string[];
    attributes?: {
      speed?: number;
      classDC?: number;
    };
    acTotal?: {
      acTotal?: number;
    };
    proficiencies?: Record<string, number>;
    perception?: number;
  };
  translations?: {
    class?: { germanName?: string };
    ancestry?: { germanName?: string };
    heritage?: { germanName?: string };
    background?: { germanName?: string };
  };
}

// Skill data with German names and linked abilities
const SKILL_DATA: Record<string, { german: string; ability: 'STR' | 'DEX' | 'CON' | 'INT' | 'WIS' | 'CHA' }> = {
  'Acrobatics': { german: 'Akrobatik', ability: 'DEX' },
  'Arcana': { german: 'Arkane Künste', ability: 'INT' },
  'Athletics': { german: 'Athletik', ability: 'STR' },
  'Crafting': { german: 'Handwerkskunst', ability: 'INT' },
  'Deception': { german: 'Täuschung', ability: 'CHA' },
  'Diplomacy': { german: 'Diplomatie', ability: 'CHA' },
  'Intimidation': { german: 'Einschüchtern', ability: 'CHA' },
  'Medicine': { german: 'Medizin', ability: 'WIS' },
  'Nature': { german: 'Naturkunde', ability: 'WIS' },
  'Occultism': { german: 'Okkultismus', ability: 'INT' },
  'Performance': { german: 'Darbietung', ability: 'CHA' },
  'Religion': { german: 'Religionskunde', ability: 'WIS' },
  'Society': { german: 'Gesellschaftskunde', ability: 'INT' },
  'Stealth': { german: 'Heimlichkeit', ability: 'DEX' },
  'Survival': { german: 'Überleben', ability: 'WIS' },
  'Thievery': { german: 'Diebeskunst', ability: 'DEX' },
};

// Proficiency bonus values
const PROFICIENCY_BONUS: Record<Proficiency, number> = {
  'UNTRAINED': 0,
  'TRAINED': 2,
  'EXPERT': 4,
  'MASTER': 6,
  'LEGENDARY': 8,
};

// Helper to format modifier with +/- sign
function formatMod(value: number): string {
  return value >= 0 ? `+${value}` : `${value}`;
}

// Helper to get ability modifier
function getAbilityMod(score: number): number {
  return Math.floor((score - 10) / 2);
}

// Helper to format bulk
function formatBulk(bulk: string | undefined): string {
  if (!bulk) return '-';
  if (bulk === 'L') return 'L';
  return bulk;
}

// Get proficiency label
function getProficiencyLabel(prof: Proficiency): string {
  const labels: Record<Proficiency, string> = {
    'UNTRAINED': 'Ungeübt',
    'TRAINED': 'Geübt',
    'EXPERT': 'Experte',
    'MASTER': 'Meister',
    'LEGENDARY': 'Legendär',
  };
  return labels[prof] || 'Ungeübt';
}

// Group feats by source
function groupFeatsBySource(feats: Character['feats']) {
  const groups: Record<string, typeof feats> = {};
  for (const feat of feats) {
    const source = feat.source || 'BONUS';
    if (!groups[source]) groups[source] = [];
    groups[source].push(feat);
  }
  return groups;
}

// Translate feat source
function translateFeatSource(source: string): string {
  const translations: Record<string, string> = {
    'CLASS': 'Klasse',
    'ANCESTRY': 'Abstammung',
    'GENERAL': 'Allgemein',
    'SKILL': 'Fertigkeit',
    'BONUS': 'Bonus',
    'ARCHETYPE': 'Archetyp',
  };
  return translations[source] || source;
}

export function generateCharacterHTML(character: Character): string {
  const abilities = character.abilities || [];
  const getAbility = (name: string) => abilities.find(a => a.ability === name)?.score || 10;

  const STR = getAbility('STR');
  const DEX = getAbility('DEX');
  const CON = getAbility('CON');
  const INT = getAbility('INT');
  const WIS = getAbility('WIS');
  const CHA = getAbility('CHA');

  // Get pathbuilder data and translations
  const pb = character.pathbuilderData as PathbuilderData | undefined;
  const translations = pb?.translations;
  const build = pb?.build;

  // Get translated or original names
  const ancestry = translations?.ancestry?.germanName || build?.ancestry || character.ancestryId || '-';
  const heritage = translations?.heritage?.germanName || build?.heritage || character.heritageId || '-';
  const background = translations?.background?.germanName || build?.background || character.backgroundId || '-';
  const charClass = translations?.class?.germanName || build?.class || character.classId || '-';
  const alignment = build?.alignment || '-';

  // Get AC from pathbuilder
  const ac = build?.acTotal?.acTotal || 10;

  // Get speed from pathbuilder
  const speed = build?.attributes?.speed || 25;

  // Calculate Perception correctly
  // Perception = WIS mod + proficiency bonus + level (if trained+)
  const proficiencies = build?.proficiencies || {};
  const perceptionProf = proficiencies['perception'] || 2; // Default to trained
  const perceptionLevelBonus = perceptionProf > 0 ? character.level : 0;
  const perception = getAbilityMod(WIS) + perceptionLevelBonus + perceptionProf;
  const perceptionProfName = perceptionProf === 0 ? 'Ungeübt' :
                             perceptionProf === 2 ? 'Geübt' :
                             perceptionProf === 4 ? 'Experte' :
                             perceptionProf === 6 ? 'Meister' :
                             perceptionProf === 8 ? 'Legendär' : 'Geübt';

  // Check if tabs have content
  const hasSpells = character.spells && character.spells.length > 0;
  const hasAlchemy = character.alchemyState && (character.formulas?.length || 0) > 0;
  const hasPreparedItems = character.preparedItems && character.preparedItems.length > 0;

  // Group items by equipped status
  const equippedItems = character.items?.filter(i => i.equipped) || [];
  const carriedItems = character.items?.filter(i => !i.equipped) || [];

  // Calculate total bulk
  const totalBulk = character.items?.reduce((sum, item) => {
    const bulk = item.equipment?.bulk;
    if (!bulk) return sum;
    if (bulk === 'L') return sum + 0.1;
    const num = parseFloat(bulk);
    return isNaN(num) ? sum : sum + num * item.quantity;
  }, 0) || 0;

  // Filter skills (exclude saves and perception)
  const EXCLUDED_SKILLS = ['Fortitude', 'Reflex', 'Will', 'Perception'];
  const filteredSkills = (character.skills || []).filter(
    (skill) => !EXCLUDED_SKILLS.includes(skill.skillName)
  );

  // Calculate skill modifiers
  const skillsWithMods = filteredSkills.map(skill => {
    const skillData = SKILL_DATA[skill.skillName];
    const germanName = skillData?.german || skill.skillName;
    const linkedAbility = skillData?.ability || 'INT';

    const abilityScore = getAbility(linkedAbility);
    const abilityMod = getAbilityMod(abilityScore);
    const profBonus = PROFICIENCY_BONUS[skill.proficiency] || 0;
    const levelBonus = skill.proficiency !== 'UNTRAINED' ? character.level : 0;
    const totalBonus = abilityMod + levelBonus + profBonus;

    const isLore = skill.skillName.toLowerCase().includes('lore');
    const displayName = isLore ? skill.skillName.replace(' Lore', '') + ' (Wissen)' : germanName;

    return {
      name: displayName,
      modifier: totalBonus,
      proficiency: skill.proficiency,
    };
  });

  // Get save values from pathbuilder proficiencies
  const getSaveTotal = (saveName: string, abilityMod: number) => {
    const prof = proficiencies[saveName] || 2; // Default to trained
    const levelBonus = prof > 0 ? character.level : 0;
    return abilityMod + levelBonus + prof;
  };

  const getSaveProfName = (saveName: string) => {
    const prof = proficiencies[saveName] || 2;
    if (prof === 0) return 'Ungeübt';
    if (prof === 2) return 'Geübt';
    if (prof === 4) return 'Experte';
    if (prof === 6) return 'Meister';
    if (prof === 8) return 'Legendär';
    return 'Geübt';
  };

  const saveReflex = getSaveTotal('reflex', getAbilityMod(DEX));
  const saveFortitude = getSaveTotal('fortitude', getAbilityMod(CON));
  const saveWill = getSaveTotal('will', getAbilityMod(WIS));

  const reflexProfName = getSaveProfName('reflex');
  const fortitudeProfName = getSaveProfName('fortitude');
  const willProfName = getSaveProfName('will');

  const html = `<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${character.name} - Charakterbogen</title>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      font-size: 11pt;
      line-height: 1.4;
      color: #1a1a1a;
      background: #fff;
      padding: 20px;
      max-width: 210mm;
      margin: 0 auto;
    }

    @media print {
      body {
        padding: 0;
        font-size: 10pt;
      }
      .page-break {
        page-break-before: always;
      }
    }

    h1 {
      font-size: 24pt;
      border-bottom: 3px solid #7c3aed;
      padding-bottom: 8px;
      margin-bottom: 16px;
      color: #7c3aed;
    }

    h2 {
      font-size: 14pt;
      background: #7c3aed;
      color: white;
      padding: 6px 12px;
      margin: 16px 0 8px 0;
      border-radius: 4px;
    }

    h3 {
      font-size: 12pt;
      color: #7c3aed;
      border-bottom: 1px solid #ddd;
      padding-bottom: 4px;
      margin: 12px 0 8px 0;
    }

    .header-info {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
      gap: 8px;
      margin-bottom: 16px;
      padding: 12px;
      background: #f8f5ff;
      border-radius: 8px;
      border: 1px solid #e9d5ff;
    }

    .header-info div {
      display: flex;
      flex-direction: column;
    }

    .header-info .label {
      font-size: 9pt;
      color: #666;
      text-transform: uppercase;
    }

    .header-info .value {
      font-weight: 600;
      font-size: 12pt;
    }

    .abilities {
      display: grid;
      grid-template-columns: repeat(6, 1fr);
      gap: 8px;
      margin-bottom: 16px;
    }

    .ability-box {
      text-align: center;
      padding: 8px;
      background: #f8f5ff;
      border: 2px solid #7c3aed;
      border-radius: 8px;
    }

    .ability-box .name {
      font-size: 10pt;
      font-weight: 600;
      color: #7c3aed;
    }

    .ability-box .mod {
      font-size: 18pt;
      font-weight: bold;
    }

    .ability-box .score {
      font-size: 9pt;
      color: #666;
    }

    .stats-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 16px;
      margin-bottom: 16px;
    }

    .stat-block {
      padding: 12px;
      background: #fafafa;
      border: 1px solid #ddd;
      border-radius: 8px;
    }

    .stat-block .title {
      font-weight: 600;
      color: #7c3aed;
      margin-bottom: 4px;
    }

    .stat-block .big-value {
      font-size: 24pt;
      font-weight: bold;
    }

    .stat-block .detail {
      font-size: 9pt;
      color: #666;
    }

    .saves-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 8px;
      margin-bottom: 16px;
    }

    .save-box {
      text-align: center;
      padding: 10px;
      background: #f0fdf4;
      border: 2px solid #22c55e;
      border-radius: 8px;
    }

    .save-box .name {
      font-size: 10pt;
      font-weight: 600;
      color: #16a34a;
    }

    .save-box .value {
      font-size: 16pt;
      font-weight: bold;
    }

    .save-box .prof {
      font-size: 8pt;
      color: #666;
    }

    .skills-list {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
      gap: 4px;
    }

    .skill-row {
      display: flex;
      justify-content: space-between;
      padding: 4px 8px;
      background: #fafafa;
      border-radius: 4px;
    }

    .skill-row:nth-child(odd) {
      background: #f0f0f0;
    }

    .skill-row .name {
      font-weight: 500;
    }

    .skill-row .value {
      font-weight: 600;
      color: #7c3aed;
    }

    .skill-row .prof {
      font-size: 8pt;
      color: #666;
      margin-left: 4px;
    }

    .feats-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
      gap: 8px;
    }

    .feat-item {
      padding: 8px;
      background: #fafafa;
      border: 1px solid #ddd;
      border-radius: 4px;
    }

    .feat-item .name {
      font-weight: 600;
    }

    .feat-item .level {
      font-size: 9pt;
      color: #666;
    }

    .items-table {
      width: 100%;
      border-collapse: collapse;
      margin-bottom: 12px;
    }

    .items-table th {
      text-align: left;
      padding: 6px 8px;
      background: #f0f0f0;
      border-bottom: 2px solid #ddd;
      font-size: 9pt;
      text-transform: uppercase;
    }

    .items-table td {
      padding: 6px 8px;
      border-bottom: 1px solid #eee;
    }

    .items-table tr:nth-child(even) {
      background: #fafafa;
    }

    .spells-section {
      margin-bottom: 16px;
    }

    .spell-level-group {
      margin-bottom: 12px;
    }

    .spell-level-title {
      font-weight: 600;
      color: #7c3aed;
      margin-bottom: 4px;
      padding: 4px 8px;
      background: #f8f5ff;
      border-radius: 4px;
    }

    .spells-list {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 4px;
      padding-left: 8px;
    }

    .spell-item {
      padding: 4px 8px;
      background: #fafafa;
      border-radius: 4px;
    }

    .alchemy-section {
      margin-bottom: 16px;
    }

    .formula-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 4px;
    }

    .formula-item {
      padding: 6px 8px;
      background: #fdf4ff;
      border: 1px solid #e9d5ff;
      border-radius: 4px;
    }

    .formula-item .name {
      font-weight: 500;
    }

    .formula-item .level {
      font-size: 9pt;
      color: #666;
    }

    .conditions-list {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
    }

    .condition-badge {
      padding: 4px 12px;
      background: #fef2f2;
      border: 1px solid #fecaca;
      border-radius: 16px;
      color: #dc2626;
      font-weight: 500;
    }

    .notes-box {
      padding: 12px;
      background: #fffbeb;
      border: 1px solid #fde68a;
      border-radius: 8px;
      white-space: pre-wrap;
    }

    .footer {
      margin-top: 24px;
      padding-top: 12px;
      border-top: 1px solid #ddd;
      font-size: 9pt;
      color: #666;
      text-align: center;
    }
  </style>
</head>
<body>
  <h1>${character.name}</h1>

  <div class="header-info">
    <div>
      <span class="label">Abstammung</span>
      <span class="value">${ancestry}</span>
    </div>
    <div>
      <span class="label">Erbe</span>
      <span class="value">${heritage}</span>
    </div>
    <div>
      <span class="label">Hintergrund</span>
      <span class="value">${background}</span>
    </div>
    <div>
      <span class="label">Klasse</span>
      <span class="value">${charClass}</span>
    </div>
    <div>
      <span class="label">Stufe</span>
      <span class="value">${character.level}</span>
    </div>
    <div>
      <span class="label">Gesinnung</span>
      <span class="value">${alignment}</span>
    </div>
  </div>

  <h2>Attribute</h2>
  <div class="abilities">
    <div class="ability-box">
      <div class="name">STR</div>
      <div class="mod">${formatMod(getAbilityMod(STR))}</div>
      <div class="score">${STR}</div>
    </div>
    <div class="ability-box">
      <div class="name">DEX</div>
      <div class="mod">${formatMod(getAbilityMod(DEX))}</div>
      <div class="score">${DEX}</div>
    </div>
    <div class="ability-box">
      <div class="name">CON</div>
      <div class="mod">${formatMod(getAbilityMod(CON))}</div>
      <div class="score">${CON}</div>
    </div>
    <div class="ability-box">
      <div class="name">INT</div>
      <div class="mod">${formatMod(getAbilityMod(INT))}</div>
      <div class="score">${INT}</div>
    </div>
    <div class="ability-box">
      <div class="name">WIS</div>
      <div class="mod">${formatMod(getAbilityMod(WIS))}</div>
      <div class="score">${WIS}</div>
    </div>
    <div class="ability-box">
      <div class="name">CHA</div>
      <div class="mod">${formatMod(getAbilityMod(CHA))}</div>
      <div class="score">${CHA}</div>
    </div>
  </div>

  <div class="stats-grid">
    <div class="stat-block">
      <div class="title">Trefferpunkte</div>
      <div class="big-value">${character.hpCurrent} / ${character.hpMax}</div>
      ${character.hpTemp ? `<div class="detail">Temporär: ${character.hpTemp}</div>` : ''}
    </div>
    <div class="stat-block">
      <div class="title">Rüstungsklasse</div>
      <div class="big-value">${ac}</div>
    </div>
    <div class="stat-block">
      <div class="title">Bewegung</div>
      <div class="big-value">${speed} ft</div>
    </div>
    <div class="stat-block">
      <div class="title">Wahrnehmung</div>
      <div class="big-value">${formatMod(perception)}</div>
      <div class="detail">${perceptionProfName}</div>
    </div>
  </div>

  <h2>Rettungswürfe</h2>
  <div class="saves-grid">
    <div class="save-box">
      <div class="name">Zähigkeit</div>
      <div class="value">${formatMod(saveFortitude)}</div>
      <div class="prof">${fortitudeProfName}</div>
    </div>
    <div class="save-box">
      <div class="name">Reflex</div>
      <div class="value">${formatMod(saveReflex)}</div>
      <div class="prof">${reflexProfName}</div>
    </div>
    <div class="save-box">
      <div class="name">Wille</div>
      <div class="value">${formatMod(saveWill)}</div>
      <div class="prof">${willProfName}</div>
    </div>
  </div>

  ${character.conditions && character.conditions.length > 0 ? `
  <h2>Zustände</h2>
  <div class="conditions-list">
    ${character.conditions.map(c => `
      <span class="condition-badge">${c.nameGerman || c.name}${c.value ? ` ${c.value}` : ''}</span>
    `).join('')}
  </div>
  ` : ''}

  <h2>Fertigkeiten</h2>
  <div class="skills-list">
    ${skillsWithMods.map(skill => `
      <div class="skill-row">
        <span class="name">${skill.name}</span>
        <span>
          <span class="value">${formatMod(skill.modifier)}</span>
          <span class="prof">(${getProficiencyLabel(skill.proficiency)})</span>
        </span>
      </div>
    `).join('')}
  </div>

  <h2>Talente</h2>
  ${Object.entries(groupFeatsBySource(character.feats || [])).map(([source, feats]) => `
    <h3>${translateFeatSource(source)}</h3>
    <div class="feats-grid">
      ${feats.map(feat => `
        <div class="feat-item">
          <span class="name">${feat.nameGerman || feat.name}</span>
          <span class="level">Stufe ${feat.level || 1}</span>
        </div>
      `).join('')}
    </div>
  `).join('')}

  <div class="page-break"></div>

  <h2>Ausrüstung</h2>
  <p style="margin-bottom: 8px; color: #666;">Traglast: ${totalBulk.toFixed(1)} Bulk</p>

  ${equippedItems.length > 0 ? `
  <h3>Angelegt</h3>
  <table class="items-table">
    <thead>
      <tr>
        <th>Gegenstand</th>
        <th>Menge</th>
        <th>Bulk</th>
      </tr>
    </thead>
    <tbody>
      ${equippedItems.map(item => `
        <tr>
          <td>${item.equipment?.nameGerman || item.equipment?.name || item.customName || '-'}</td>
          <td>${item.quantity}</td>
          <td>${formatBulk(item.equipment?.bulk)}</td>
        </tr>
      `).join('')}
    </tbody>
  </table>
  ` : ''}

  ${carriedItems.length > 0 ? `
  <h3>Mitgeführt</h3>
  <table class="items-table">
    <thead>
      <tr>
        <th>Gegenstand</th>
        <th>Menge</th>
        <th>Bulk</th>
      </tr>
    </thead>
    <tbody>
      ${carriedItems.map(item => `
        <tr>
          <td>${item.equipment?.nameGerman || item.equipment?.name || item.customName || '-'}</td>
          <td>${item.quantity}</td>
          <td>${formatBulk(item.equipment?.bulk)}</td>
        </tr>
      `).join('')}
    </tbody>
  </table>
  ` : ''}

  ${hasSpells ? `
  <h2>Zauber</h2>
  <div class="spells-section">
    ${Object.entries(
      (character.spells || []).reduce((acc, spell) => {
        const level = spell.spellLevel || 0;
        if (!acc[level]) acc[level] = [];
        acc[level].push(spell);
        return acc;
      }, {} as Record<number, typeof character.spells>)
    ).sort(([a], [b]) => Number(a) - Number(b)).map(([level, spells]) => `
      <div class="spell-level-group">
        <div class="spell-level-title">${level === '0' ? 'Zaubertricks' : `Grad ${level}`}</div>
        <div class="spells-list">
          ${spells!.map(spell => `
            <div class="spell-item">${spell.nameGerman || spell.name}</div>
          `).join('')}
        </div>
      </div>
    `).join('')}
  </div>
  ` : ''}

  ${hasAlchemy || hasPreparedItems ? `
  <h2>Alchemie</h2>
  <div class="alchemy-section">
    ${character.alchemyState ? `
    <div class="stats-grid" style="margin-bottom: 12px;">
      <div class="stat-block">
        <div class="title">Vielseitige Phiolen</div>
        <div class="big-value">${character.alchemyState.versatileVialsCurrent} / ${character.alchemyState.versatileVialsMax}</div>
      </div>
      <div class="stat-block">
        <div class="title">Fortgeschrittene Alchemie</div>
        <div class="big-value">${character.alchemyState.advancedAlchemyBatch} / ${character.alchemyState.advancedAlchemyMax}</div>
        <div class="detail">Chargen verwendet</div>
      </div>
    </div>
    ` : ''}

    ${(character.formulas?.length || 0) > 0 ? `
    <h3>Formelbuch</h3>
    <div class="formula-grid">
      ${character.formulas!.map(formula => `
        <div class="formula-item">
          <span class="name">${formula.equipment?.nameGerman || formula.nameGerman || formula.name}</span>
          ${formula.equipment?.level !== undefined ? `<span class="level"> (Stufe ${formula.equipment.level})</span>` : ''}
        </div>
      `).join('')}
    </div>
    ` : ''}

    ${hasPreparedItems ? `
    <h3>Vorbereitete Gegenstände</h3>
    <table class="items-table">
      <thead>
        <tr>
          <th>Gegenstand</th>
          <th>Menge</th>
          <th>Typ</th>
        </tr>
      </thead>
      <tbody>
        ${character.preparedItems!.map(item => `
          <tr>
            <td>${item.equipment?.nameGerman || item.nameGerman || item.name}</td>
            <td>${item.quantity}</td>
            <td>${item.isInfused ? 'Infundiert' : 'Hergestellt'}</td>
          </tr>
        `).join('')}
      </tbody>
    </table>
    ` : ''}
  </div>
  ` : ''}

  <div class="footer">
    Exportiert am ${new Date().toLocaleDateString('de-DE', {
      year: 'numeric',
      month: 'long',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    })} • Dimension 47
  </div>
</body>
</html>`;

  return html;
}

export function downloadCharacterHTML(character: Character): void {
  const html = generateCharacterHTML(character);
  const blob = new Blob([html], { type: 'text/html;charset=utf-8' });
  const url = URL.createObjectURL(blob);

  const link = document.createElement('a');
  link.href = url;
  link.download = `${character.name.replace(/[^a-zA-Z0-9äöüÄÖÜß\s-]/g, '')}_Charakterbogen.html`;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);

  URL.revokeObjectURL(url);
}
