import React, { useEffect, useState, useMemo } from 'react';
import { DraggableWindow } from './DraggableWindow';
import { apiFetch } from '../../api/client';

interface Props { id: string; charName: string; zIndex: number; }

const ELEMENTS = ['Typeless','Slash','Pierce','Bludgeon','Fire','Cold','Acid','Electric'];

function getDmg(side: any, atkType: string, el: string): number {
  return (side?.[atkType]?.[el]?.total_normal_damage ?? 0) + (side?.[atkType]?.[el]?.total_crit_damage ?? 0);
}

function flatten(side: any) {
  let r = { attacks: 0, failed: 0, crits: 0, normalDmg: 0, maxNormal: 0, critDmg: 0, maxCrit: 0 };
  if (!side) return r;
  for (const byEl of Object.values(side) as any[]) {
    for (const s of Object.values(byEl) as any[]) {
      r.attacks += s.total_attacks ?? 0;
      r.failed += s.failed_attacks ?? 0;
      r.crits += s.crits ?? 0;
      r.normalDmg += s.total_normal_damage ?? 0;
      r.maxNormal = Math.max(r.maxNormal, s.max_normal_damage ?? 0);
      r.critDmg += s.total_crit_damage ?? 0;
      r.maxCrit = Math.max(r.maxCrit, s.max_crit_damage ?? 0);
    }
  }
  return r;
}

function flattenType(side: any, type: string) {
  let r = { attacks: 0, failed: 0 };
  const byEl = side?.[type];
  if (!byEl) return r;
  for (const s of Object.values(byEl) as any[]) { r.attacks += s.total_attacks ?? 0; r.failed += s.failed_attacks ?? 0; }
  return r;
}

export const CombatStatsWindow: React.FC<Props> = ({ id, charName, zIndex }) => {
  const [data, setData] = useState<any>(null);
  const [mode, setMode] = useState<'session' | 'lifetime'>('session');
  const [selected, setSelected] = useState<string | null>(null);

  useEffect(() => {
    apiFetch<any>(`/combat-stats/${encodeURIComponent(charName)}`).then(setData).catch(() => {});
    const iv = setInterval(() => {
      apiFetch<any>(`/combat-stats/${encodeURIComponent(charName)}`).then(setData).catch(() => {});
    }, 10000);
    return () => clearInterval(iv);
  }, [charName]);

  const state = data?.[mode];
  const monsters = state?.monsters ?? {};
  const names = Object.keys(monsters).filter(n => n !== '__cloak_surges__').sort();

  // Aggregate for selected or all
  const agg = useMemo(() => {
    let offense: any = {}, defense: any = {}, aeth = 0, cloak = 0;
    const list = selected ? [monsters[selected]].filter(Boolean) : names.map(n => monsters[n]);
    for (const m of list) {
      if (!m) continue;
      for (const [at, byEl] of Object.entries(m.offense ?? {})) {
        if (!offense[at]) offense[at] = {};
        for (const [el, s] of Object.entries(byEl as any)) {
          if (!offense[at][el]) offense[at][el] = { total_attacks:0, failed_attacks:0, crits:0, total_normal_damage:0, max_normal_damage:0, total_crit_damage:0, max_crit_damage:0 };
          const t = offense[at][el]; const src = s as any;
          t.total_attacks += src.total_attacks ?? 0; t.failed_attacks += src.failed_attacks ?? 0; t.crits += src.crits ?? 0;
          t.total_normal_damage += src.total_normal_damage ?? 0; t.max_normal_damage = Math.max(t.max_normal_damage, src.max_normal_damage ?? 0);
          t.total_crit_damage += src.total_crit_damage ?? 0; t.max_crit_damage = Math.max(t.max_crit_damage, src.max_crit_damage ?? 0);
        }
      }
      for (const [at, byEl] of Object.entries(m.defense ?? {})) {
        if (!defense[at]) defense[at] = {};
        for (const [el, s] of Object.entries(byEl as any)) {
          if (!defense[at][el]) defense[at][el] = { total_attacks:0, failed_attacks:0, crits:0, total_normal_damage:0, max_normal_damage:0, total_crit_damage:0, max_crit_damage:0 };
          const t = defense[at][el]; const src = s as any;
          t.total_attacks += src.total_attacks ?? 0; t.failed_attacks += src.failed_attacks ?? 0;
          t.total_normal_damage += src.total_normal_damage ?? 0; t.max_normal_damage = Math.max(t.max_normal_damage, src.max_normal_damage ?? 0);
          t.total_crit_damage += src.total_crit_damage ?? 0; t.max_crit_damage = Math.max(t.max_crit_damage, src.max_crit_damage ?? 0);
        }
      }
      aeth += m.aetheria_surges ?? 0;
      cloak += m.cloak_surges ?? 0;
    }
    if (monsters['__cloak_surges__'] && !selected) cloak += monsters['__cloak_surges__'].cloak_surges ?? 0;
    return { offense, defense, aeth, cloak };
  }, [monsters, names, selected]);

  const off = flatten(agg.offense);
  const defMM = flattenType(agg.defense, 'MeleeMissile');
  const defMag = flattenType(agg.defense, 'Magic');
  const hitRate = off.attacks > 0 ? ((off.attacks - off.failed) / off.attacks * 100).toFixed(0) : '0';
  const evadeRate = defMM.attacks > 0 ? (defMM.failed / defMM.attacks * 100).toFixed(0) : '0';
  const resistRate = defMag.attacks > 0 ? (defMag.failed / defMag.attacks * 100).toFixed(0) : '0';
  const hits = off.attacks - off.failed;
  const normalHits = hits - off.crits;
  const avgN = normalHits > 0 ? Math.round(off.normalDmg / normalHits) : 0;
  const avgC = off.crits > 0 ? Math.round(off.critDmg / off.crits) : 0;
  const critPct = hits > 0 ? (off.crits / hits * 100).toFixed(1) : '0';
  const fmtN = (n: number) => n === 0 ? '' : n.toLocaleString();

  return (
    <DraggableWindow id={id} title={`Combat: ${charName}`} zIndex={zIndex} width={640} height={520}>
      {/* Toggle + Clear */}
      <div style={{ display: 'flex', gap: 4, padding: '4px 8px', borderBottom: '1px solid #333', alignItems: 'center' }}>
        <button className={`ml-stats-range-btn ${mode === 'session' ? 'active' : ''}`} onClick={() => setMode('session')}>Session</button>
        <button className={`ml-stats-range-btn ${mode === 'lifetime' ? 'active' : ''}`} onClick={() => setMode('lifetime')}>Lifetime</button>
        <div style={{ flex: 1 }} />
        {mode === 'session' && (
          <button style={{ fontSize: '0.6rem', padding: '2px 8px', background: 'rgba(204,68,68,0.15)', color: '#c66', border: '1px solid rgba(204,68,68,0.3)', borderRadius: 3, cursor: 'pointer' }}
            onClick={() => { if (confirm('Clear current session stats?')) { /* Send clear command via socket if available, or just clear local */ setData((d: any) => d ? { ...d, session: { total_damage_given: 0, total_damage_received: 0, total_kills: 0, total_aetheria_surges: 0, total_cloak_surges: 0, monsters: {} } } : d); } }}>
            Clear Session
          </button>
        )}
      </div>
      <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>
        {/* Monster list (left) */}
        <div style={{ width: 240, borderRight: '1px solid #333', overflowY: 'auto', fontSize: '0.72rem' }}>
          <div style={{ display: 'flex', padding: '3px 6px', borderBottom: '1px solid #333', color: '#777', fontSize: '0.65rem', fontWeight: 600 }}>
            <span style={{ width: 14 }}></span><span style={{ flex: 1 }}>Monster</span>
            <span style={{ width: 40, textAlign: 'right' }}>Kills</span><span style={{ width: 55, textAlign: 'right' }}>Dmg</span>
          </div>
          {/* All row */}
          <div style={{ display: 'flex', padding: '3px 6px', cursor: 'pointer', background: selected === null ? '#2a3a4a' : '', borderBottom: '1px solid #222', color: '#ddd' }}
            onClick={() => setSelected(null)}>
            <span style={{ width: 14, color: '#888' }}>{selected === null ? '*' : ''}</span>
            <span style={{ flex: 1 }}>All</span>
            <span style={{ width: 40, textAlign: 'right' }}>{fmtN(state?.total_kills ?? 0)}</span>
            <span style={{ width: 55, textAlign: 'right' }}>{fmtN(state?.total_damage_given ?? 0)}</span>
          </div>
          {names.map(n => {
            const m = monsters[n];
            return (
              <div key={n} style={{ display: 'flex', padding: '2px 6px', cursor: 'pointer', background: selected === n ? '#2a3a4a' : '',
                borderBottom: '1px solid #1a1a1a', color: '#ccc' }} onClick={() => setSelected(n)}>
                <span style={{ width: 14, color: '#888' }}>{selected === n ? '*' : ''}</span>
                <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{n}</span>
                <span style={{ width: 40, textAlign: 'right' }}>{fmtN(m.kill_count)}</span>
                <span style={{ width: 55, textAlign: 'right' }}>{fmtN(m.damage_given)}</span>
              </div>
            );
          })}
        </div>
        {/* Breakdown grid (right) */}
        <div style={{ flex: 1, overflowY: 'auto', padding: 6, fontSize: '0.72rem' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead>
              <tr style={{ color: '#777', fontSize: '0.65rem' }}>
                <th style={{ textAlign: 'left', padding: '1px 4px' }}></th>
                <th style={{ textAlign: 'right', padding: '1px 3px' }}>Given M/M</th>
                <th style={{ textAlign: 'right', padding: '1px 3px' }}>Given Mag</th>
                <th style={{ width: 4 }}></th>
                <th style={{ textAlign: 'right', padding: '1px 3px' }}>Recv M/M</th>
                <th style={{ textAlign: 'right', padding: '1px 3px' }}>Recv Mag</th>
                <th style={{ width: 4 }}></th>
                <th style={{ textAlign: 'left', padding: '1px 3px' }}>Stats</th>
                <th style={{ textAlign: 'right', padding: '1px 3px' }}></th>
              </tr>
            </thead>
            <tbody>
              {ELEMENTS.map((el, i) => {
                const stats = [
                  ['Evades', defMM.attacks > 0 ? `${fmtN(defMM.attacks)} (${evadeRate}%)` : ''],
                  ['Resists', defMag.attacks > 0 ? `${fmtN(defMag.attacks)} (${resistRate}%)` : ''],
                  ['A.Surges', agg.aeth > 0 ? `${fmtN(agg.aeth)}` : ''],
                  ['C.Surges', agg.cloak > 0 ? `${fmtN(agg.cloak)}` : ''],
                  ['', ''], ['', ''],
                  ['Av/Mx', avgN > 0 ? `${fmtN(avgN)} / ${fmtN(off.maxNormal)}` : ''],
                  ['Crits', off.crits > 0 ? `${fmtN(off.crits)} (${critPct}%)` : ''],
                ][i] ?? ['', ''];
                return (
                  <tr key={el}>
                    <td style={{ padding: '1px 4px', color: '#888' }}>{el}</td>
                    <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{fmtN(getDmg(agg.offense, 'MeleeMissile', el))}</td>
                    <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{fmtN(getDmg(agg.offense, 'Magic', el))}</td>
                    <td></td>
                    <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{fmtN(getDmg(agg.defense, 'MeleeMissile', el))}</td>
                    <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{fmtN(getDmg(agg.defense, 'Magic', el))}</td>
                    <td></td>
                    <td style={{ padding: '1px 3px', color: '#777', fontWeight: 600, fontSize: '0.65rem' }}>{stats[0]}</td>
                    <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{stats[1]}</td>
                  </tr>
                );
              })}
              <tr>
                <td colSpan={9} style={{ height: 4 }}></td>
              </tr>
              <tr>
                <td style={{ padding: '1px 4px', color: '#888', fontWeight: 600 }}>Total</td>
                <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{fmtN(ELEMENTS.reduce((s, e) => s + getDmg(agg.offense, 'MeleeMissile', e), 0))}</td>
                <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{fmtN(ELEMENTS.reduce((s, e) => s + getDmg(agg.offense, 'Magic', e), 0))}</td>
                <td></td>
                <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{fmtN(ELEMENTS.reduce((s, e) => s + getDmg(agg.defense, 'MeleeMissile', e), 0))}</td>
                <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{fmtN(ELEMENTS.reduce((s, e) => s + getDmg(agg.defense, 'Magic', e), 0))}</td>
                <td></td>
                <td style={{ padding: '1px 3px', color: '#777', fontWeight: 600, fontSize: '0.65rem' }}>Total</td>
                <td style={{ textAlign: 'right', padding: '1px 3px', color: '#ccc' }}>{fmtN(off.normalDmg + off.critDmg)}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </DraggableWindow>
  );
};
