// Company KPIs — define and track custom, industry-specific metrics
// Computed data sources — KPIs can auto-pull from live data instead of manual entry
const KPI_SOURCES = {
  manual:        { label: 'Manual entry', compute: null },
  won_value:     { label: 'Closed-won value (auto)', unit: 'currency', compute: (d) => d.deals.filter(x => x.stage === 'sold').reduce((s, x) => s + x.value, 0) },
  pipeline_value:{ label: 'Active pipeline value (auto)', unit: 'currency', compute: (d) => d.deals.filter(x => x.stage !== 'sold' && x.stage !== 'lost').reduce((s, x) => s + x.value, 0) },
  deals_sold:    { label: 'Deals sold — count (auto)', unit: 'count', compute: (d) => d.deals.filter(x => x.stage === 'sold').length },
  active_deals:  { label: 'Active deals — count (auto)', unit: 'count', compute: (d) => d.deals.filter(x => x.stage !== 'sold' && x.stage !== 'lost').length },
  win_rate:      { label: 'Win rate % (auto)', unit: 'percent', compute: (d) => { const w = d.deals.filter(x => x.stage === 'sold').length; const l = d.deals.filter(x => x.stage === 'lost').length; return w + l ? Math.round(w / (w + l) * 100) : 0; } },
  avg_deal:      { label: 'Average deal size (auto)', unit: 'currency', compute: (d) => { const w = d.deals.filter(x => x.stage === 'sold'); return w.length ? Math.round(w.reduce((s, x) => s + x.value, 0) / w.length) : 0; } },
  total_contacts:{ label: 'Total contacts (auto)', unit: 'count', compute: (d) => d.contacts.length },
  // Calendar / activity-linked (auto-calculated from booked appointments, quotes & logged activity)
  appts_booked:  { label: 'Appointments booked — from calendar (auto)', unit: 'appts', compute: (d) => d.deals.filter(x => x.designApptDate).length },
  quotes_presented: { label: 'Quotes presented — from calendar (auto)', unit: 'count', compute: (d) => d.deals.filter(x => x.quotePresentationDate).length },
  calls_made:    { label: 'Calls logged — from activity (auto)', unit: 'calls', compute: (d) => d.deals.reduce((s, x) => s + (x.activities || []).filter(a => a.type === 'call').length, 0) },
  meetings_held: { label: 'Meetings/visits — from activity (auto)', unit: 'count', compute: (d) => d.deals.reduce((s, x) => s + (x.activities || []).filter(a => a.type === 'meeting').length, 0) },
  avg_rating:    { label: 'Avg customer rating — from reviews (auto)', unit: 'rating', compute: (d) => { const r = d.contacts.filter(c => c.rating > 0); return r.length ? (r.reduce((s, c) => s + c.rating, 0) / r.length) : 0; } },
};

const KPI_UNITS = {
  currency: { label: '$ Dollars', fmt: (v) => '$' + Math.round(Number(v)).toLocaleString(), prefix: '$' },
  count:    { label: 'Count',     fmt: (v) => Number(v).toLocaleString(), prefix: '' },
  calls:    { label: 'Calls',     fmt: (v) => Number(v).toLocaleString() + ' calls', prefix: '' },
  appts:    { label: 'Appointments', fmt: (v) => Number(v).toLocaleString() + ' appts', prefix: '' },
  percent:  { label: '% Percent',  fmt: (v) => Number(v) + '%', prefix: '' },
  hours:    { label: 'Hours',     fmt: (v) => Number(v).toLocaleString() + ' hrs', prefix: '' },
  rating:   { label: 'Rating (/5)', fmt: (v) => Number(v).toFixed(1) + ' / 5', prefix: '' },
};

const DEFAULT_KPIS = [
  { id: 'k1', name: 'Appointments booked', unit: 'appts', target: 60, actual: 0, targetPeriod: 'month', owner: 'All locations', source: 'appts_booked' },
  { id: 'k2', name: 'Follow-up calls logged', unit: 'calls', target: 400, actual: 0, targetPeriod: 'month', owner: 'All locations', source: 'calls_made' },
  { id: 'k3', name: 'Customer satisfaction', unit: 'rating', target: 4.5, actual: 0, targetPeriod: 'year', owner: 'All locations', source: 'avg_rating' },
  { id: 'k4', name: 'Quote-to-sale conversion', unit: 'percent', target: 50, actual: 0, targetPeriod: 'year', owner: 'All locations', source: 'win_rate' },
  { id: 'k5', name: 'Closed-won (financial year)', unit: 'currency', target: 200000, actual: 0, targetPeriod: 'month', owner: 'All locations', source: 'won_value' },
  { id: 'k6', name: 'Deals sold', unit: 'count', target: 13, actual: 0, targetPeriod: 'month', owner: 'All locations', source: 'deals_sold' },
];

function periodMonths(p) { return p === 'month' ? 1 : p === 'quarter' ? 3 : p === '6month' ? 6 : 12; }
function rangeMonthsCount(r) { return r === 'month' ? 1 : r === 'quarter' ? 3 : 12; }

function kpiDealInRange(deal, range) {
  const d = deal.created;
  if (!d || range === 'all') return true;
  const starts = { month: '2026-05-01', quarter: '2026-04-01', fy: '2025-07-01', '12m': '2025-05-27' };
  return d >= (starts[range] || '0000-01-01');
}

function monthsForRange(range) {
  const FYM = window.FY_MONTHS || [];
  if (range === 'month') return ['2026-05'];
  if (range === 'quarter') { const q = (FYM.find(m => m.key === '2026-05') || {}).q || 4; return FYM.filter(m => m.q === q).map(m => m.key); }
  return FYM.map(m => m.key);
}

function CustomKPIs({ currentUser, deals, contacts, stages, showrooms, reps, targets, kpis, kpiTargets, allowedShowrooms, globalShowroom }) {
  const canEdit = ['admin', 'leadership', 'manager'].includes(currentUser.role);
  const isAdmin = canEdit;

  const allowed = allowedShowrooms || (showrooms || []).map(s => s.id);
  const visibleShowrooms = (showrooms || []).filter(s => allowed.includes(s.id));
  const [fDesigner, setFDesigner] = React.useState('all');
  const [fRange, setFRange] = React.useState('all');
  // Showroom scope comes from the GLOBAL switcher at the top — no duplicate filter here
  const fShowroom = globalShowroom || 'all';

  // If the global showroom scope changes to one this designer filter no longer fits, reset it
  React.useEffect(() => { setFDesigner('all'); }, [fShowroom]);

  const repsForShowroom = fShowroom === 'all'
    ? (reps || [])
    : (reps || []).filter(r => (r.works || []).includes(fShowroom));

  const filteredDeals = (deals || []).filter(d => {
    if (fShowroom !== 'all' && d.showroom !== fShowroom) return false;
    if (fDesigner !== 'all' && d.rep !== fDesigner) return false;
    if (!kpiDealInRange(d, fRange)) return false;
    return true;
  });

  const dataCtx = { deals: filteredDeals, contacts: contacts || [], stages: stages || [] };
  const computeActual = (k) => {
    const src = KPI_SOURCES[k.source];
    if (src && src.compute) return src.compute(dataCtx);
    return k.actual;
  };

  // Designers currently in scope (showroom + designer filter) — drives target scaling
  const scopeReps = (fDesigner !== 'all'
    ? (reps || []).filter(r => r.id === fDesigner)
    : repsForShowroom
  );

  const targetFromTargetsTab = () => {
    if (!targets) return null;
    const repIds = scopeReps.map(r => r.id);
    const monthKeys = monthsForRange(fRange);
    let sum = 0;
    repIds.forEach(rid => { if (targets[rid]) monthKeys.forEach(mk => { sum += targets[rid][mk] || 0; }); });
    return sum;
  };
  // Per-KPI per-designer MONTHLY targets entered in Admin → KPIs & Targets (the linked source)
  const kpiTargetFromGrid = (k) => {
    if (!kpiTargets || !kpiTargets[k.id]) return null;
    const monthKeys = monthsForRange(fRange);
    const vals = [];
    let sum = 0;
    scopeReps.forEach(r => {
      const rt = kpiTargets[k.id][r.id];
      if (rt) monthKeys.forEach(mk => { if (rt[mk] != null && rt[mk] !== '') { sum += Number(rt[mk]) || 0; vals.push(Number(rt[mk]) || 0); } });
    });
    if (vals.length === 0) return null;
    if (k.unit === 'rating' || k.unit === 'percent') return Math.round((vals.reduce((a, b) => a + b, 0) / vals.length) * 10) / 10;
    return Math.round(sum);
  };
  const effectiveTarget = (k) => {
    // Targets entered per designer/month in Admin take priority (the linked KPI targets)
    const grid = kpiTargetFromGrid(k);
    if (grid != null) return grid;
    // $ closed-won always pulls the real per-designer dollar targets from the Targets tab
    if (k.source === 'won_value') { const t = targetFromTargetsTab(); if (t && t > 0) return t; }
    const months = rangeMonthsCount(fRange);
    const periodM = periodMonths(k.targetPeriod || 'month');
    // Rating / percent goals don't sum — they stay a flat goal regardless of scope
    if (k.unit === 'rating' || k.unit === 'percent') return k.target;
    // Precise per-salesperson targets: sum each in-scope designer's monthly target
    if (k.perDesigner && Object.keys(k.perDesigner).length > 0) {
      let sum = 0;
      scopeReps.forEach(r => {
        const monthly = (k.perDesigner[r.id] != null ? k.perDesigner[r.id] : (k.target || 0)) / periodM;
        sum += monthly;
      });
      return Math.round(sum * months);
    }
    const totalReps = (reps || []).length || 1;
    const inScope = scopeReps.length || totalReps;
    const monthly = (k.target || 0) / periodM;
    if (k.basis === 'perPerson') {
      // target is per team member → multiply by people in scope
      return Math.round(monthly * inScope * months);
    }
    // default 'team' basis: target is a whole-team total → pro-rate to people in scope
    return Math.round(monthly * months * (inScope / totalReps));
  };

  return (
    <div>
      <div className="card" style={{ marginBottom: 16, padding: '14px 18px', display: 'flex', alignItems: 'center', gap: 14, background: 'var(--info-soft)', border: '1px solid oklch(0.85 0.04 240)' }}>
        <div style={{ width: 32, height: 32, borderRadius: 16, background: 'var(--info)', color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
          <Icon name="target" size={16} color="white"/>
        </div>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 13, fontWeight: 600, color: 'oklch(0.3 0.1 240)', marginBottom: 2 }}>Company KPIs</div>
          <div style={{ fontSize: 12, color: 'oklch(0.35 0.08 240)' }}>
            Track metrics specific to your business — calls made, appointments booked, satisfaction scores, anything. Set a target and current value; the dashboard shows progress.
          </div>
        </div>
        {isAdmin && <span className="pill" style={{ fontSize: 10.5 }}><Icon name="sliders" size={11}/> Manage in Admin → KPIs &amp; Targets</span>}
      </div>

      <div className="filters-bar" style={{ borderRadius: 'var(--r-lg)', border: '1px solid var(--border)', marginBottom: 16, padding: '10px 14px' }}>
        <Icon name="filter" size={13} style={{ color: 'var(--ink-3)' }}/>
        <select className="sel" value={fDesigner} onChange={(e) => setFDesigner(e.target.value)}>
          <option value="all">All {window.T ? window.T('reps_lc') : 'designers'}</option>
          {repsForShowroom.map(r => <option key={r.id} value={r.id}>{r.name}</option>)}
        </select>
        <select className="sel" value={fRange} onChange={(e) => setFRange(e.target.value)}>
          <option value="all">All time</option>
          <option value="month">This month</option>
          <option value="quarter">This quarter</option>
          <option value="fy">This financial year</option>
          <option value="12m">Last 12 months</option>
        </select>
        {(fDesigner !== 'all' || fRange !== 'all') && (
          <button className="filter-chip" onClick={() => { setFDesigner('all'); setFRange('all'); }}>Clear filters</button>
        )}
        <span style={{ marginLeft: 'auto', fontSize: 11.5, color: 'var(--ink-4)' }} className="num">{filteredDeals.length} deals in scope</span>
      </div>

      <div className="grid-kpis" style={{ gridTemplateColumns: 'repeat(2, 1fr)' }}>
        {kpis.map(k => {
          const unit = KPI_UNITS[k.unit] || KPI_UNITS.count;
          const actual = computeActual(k);
          const target = effectiveTarget(k);
          const isAuto = k.source && k.source !== 'manual';
          const linkedTarget = k.source === 'won_value' && targets && targetFromTargetsTab() > 0;
          const pct = target > 0 ? Math.min(actual / target, 1.5) : 0;
          const onTrack = pct >= 0.9;
          const color = onTrack ? 'var(--won)' : pct >= 0.6 ? 'oklch(0.6 0.13 70)' : 'var(--lost)';
          return (
            <div key={k.id} className="kpi">
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>
                <div className="kpi-label">{k.name}</div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                  <span className="pill" style={{ fontSize: 9, padding: '1px 6px', background: isAuto ? 'var(--info-soft)' : 'var(--surface-3)', color: isAuto ? 'oklch(0.4 0.09 240)' : 'var(--ink-3)' }}>
                    {isAuto ? '🔗 Auto' : '✎ Manual'}
                  </span>
                </div>
              </div>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 8 }}>
                <span className="kpi-value num" style={{ fontSize: 24 }}>{unit.fmt(actual)}</span>
                <span style={{ fontSize: 13, color: 'var(--ink-3)' }} className="num">/ {unit.fmt(target)}</span>
              </div>
              <div style={{ height: 8, background: 'var(--surface-3)', borderRadius: 4, marginTop: 12, overflow: 'hidden' }}>
                <div style={{ height: '100%', width: Math.min(pct, 1) * 100 + '%', background: color, borderRadius: 4, transition: 'width 0.4s' }}></div>
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, fontSize: 11.5, color: 'var(--ink-3)' }}>
                <span>{linkedTarget ? '\uD83C\uDFAF Target from Targets tab' : ('Target: ' + (k.targetPeriod || 'month') + 'ly \u00b7 ' + k.owner)}</span>
                <span style={{ color, fontWeight: 600 }} className="num">{Math.round(pct * 100)}%</span>
              </div>
            </div>
          );
        })}
      </div>

    </div>
  );
}

function KPIEditor({ kpi, reps, onClose, onSave }) {
  const [d, setD] = React.useState(kpi || { name: '', unit: 'count', target: '', actual: 0, targetPeriod: 'month', basis: 'team', perDesigner: {}, owner: 'All locations', source: 'manual' });
  const set = (k, v) => setD(p => ({ ...p, [k]: v }));
  const setPer = (rid, v) => setD(p => {
    const pd = { ...(p.perDesigner || {}) };
    if (v === '' || v == null) delete pd[rid]; else pd[rid] = parseFloat(v) || 0;
    return { ...p, perDesigner: pd };
  });
  const valid = d.name.trim() && d.target !== '';
  const periodWord = (d.targetPeriod || 'month') === 'month' ? 'per month' : (d.targetPeriod === 'quarter' ? 'per quarter' : d.targetPeriod === '6month' ? 'per 6 months' : 'per year');
  const isFlatGoal = d.unit === 'rating' || d.unit === 'percent';
  const showPerPerson = !isFlatGoal && d.source !== 'won_value';
  return (
    <div>
      <div className="detail-overlay" onClick={onClose} style={{ zIndex: 52 }}/>
      <div className="invite-modal" style={{ zIndex: 53, width: 480 }}>
        <div style={{ padding: '18px 22px 14px', borderBottom: '1px solid var(--border)' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <div style={{ fontSize: 18, fontWeight: 600 }}>{kpi ? 'Edit KPI' : 'New KPI'}</div>
            <button className="detail-close" style={{ marginLeft: 'auto' }} onClick={onClose}><Icon name="close" size={16}/></button>
          </div>
        </div>
        <div style={{ padding: '18px 22px' }}>
          <div className="detail-field" style={{ marginBottom: 14 }}>
            <span className="lbl">KPI name</span>
            <input value={d.name} onChange={(e) => set('name', e.target.value)} placeholder="e.g. Follow-up calls made" autoFocus/>
          </div>
          <div className="detail-field" style={{ marginBottom: 14 }}>
            <span className="lbl">Data source</span>
            <select value={d.source || 'manual'} onChange={(e) => {
              const src = KPI_SOURCES[e.target.value];
              set('source', e.target.value);
              if (src && src.unit) set('unit', src.unit);
            }}>
              {Object.entries(KPI_SOURCES).map(([k, s]) => <option key={k} value={k}>{s.label}</option>)}
            </select>
            <span style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 4 }}>
              {d.source && d.source !== 'manual' ? 'This KPI updates automatically from your live deal data.' : 'You enter the current value yourself.'}
            </span>
          </div>
          <div className="detail-grid">
            <div className="detail-field">
              <span className="lbl">Measured in</span>
              <select value={d.unit} onChange={(e) => set('unit', e.target.value)} disabled={d.source && d.source !== 'manual'}>
                {Object.entries(KPI_UNITS).map(([k, u]) => <option key={k} value={k}>{u.label}</option>)}
              </select>
            </div>
            <div className="detail-field">
              <span className="lbl">Target period</span>
              <select value={d.targetPeriod || 'month'} onChange={(e) => set('targetPeriod', e.target.value)}>
                <option value="month">Monthly</option>
                <option value="quarter">Quarterly</option>
                <option value="6month">6-monthly</option>
                <option value="year">Yearly</option>
              </select>
            </div>
            <div className="detail-field">
              <span className="lbl">Target {periodWord}{showPerPerson && d.basis === 'perPerson' ? ' · per person' : (showPerPerson ? ' · whole team' : '')}</span>
              <input type="number" value={d.target} onChange={(e) => set('target', parseFloat(e.target.value) || 0)}/>
            </div>
            <div className="detail-field">
              <span className="lbl">Current actual {d.source && d.source !== 'manual' ? '(auto)' : ''}</span>
              <input type="number" value={d.actual} onChange={(e) => set('actual', parseFloat(e.target.value) || 0)} disabled={d.source && d.source !== 'manual'} style={(d.source && d.source !== 'manual') ? { opacity: 0.5 } : null}/>
            </div>
            <div className="detail-field" style={{ gridColumn: '1 / -1' }}>
              <span className="lbl">Applies to</span>
              <input value={d.owner} onChange={(e) => set('owner', e.target.value)} placeholder="e.g. All locations, or a specific team"/>
            </div>
          </div>

          {showPerPerson && (
            <div style={{ marginTop: 16 }}>
              <div className="detail-field" style={{ marginBottom: 10 }}>
                <span className="lbl">How is this target set?</span>
                <select value={d.basis || 'team'} onChange={(e) => set('basis', e.target.value)}>
                  <option value="team">Whole-team total — splits across whoever's in view</option>
                  <option value="perPerson">Per team member — multiplies by people in view</option>
                </select>
                <span style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 4 }}>
                  Either way the figure adjusts automatically when you filter by {window.T ? window.T('location').toLowerCase() : 'showroom'}, team member or time.
                </span>
              </div>

              <details style={{ border: '1px solid var(--border)', borderRadius: 8, padding: '10px 12px' }}>
                <summary style={{ cursor: 'pointer', fontSize: 12.5, fontWeight: 500, color: 'var(--ink-2)' }}>
                  Set targets by team member ({Object.keys(d.perDesigner || {}).length} customised)
                </summary>
                <div style={{ marginTop: 10, fontSize: 11, color: 'var(--ink-3)', marginBottom: 8 }}>
                  Leave blank to use the default above ({d.target || 0} {periodWord}). Set a {periodWord} figure for any individual.
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: '6px 10px', maxHeight: 200, overflowY: 'auto' }}>
                  {(reps || []).map(r => (
                    <React.Fragment key={r.id}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12.5 }}>
                        <Avatar name={r.name} sz="sm"/> {r.name}
                      </div>
                      <input
                        type="number"
                        value={(d.perDesigner && d.perDesigner[r.id] != null) ? d.perDesigner[r.id] : ''}
                        placeholder={String(d.target || 0)}
                        onChange={(e) => setPer(r.id, e.target.value)}
                        style={{ width: 100, padding: '4px 8px', border: '1px solid var(--border)', borderRadius: 4, fontSize: 12.5, textAlign: 'right' }}
                      />
                    </React.Fragment>
                  ))}
                </div>
              </details>
            </div>
          )}
        </div>
        <div style={{ padding: '14px 22px', borderTop: '1px solid var(--border)', background: 'var(--surface-2)', display: 'flex', gap: 8 }}>
          <button className="btn" onClick={onClose}>Cancel</button>
          <button className="btn primary" disabled={!valid} style={{ marginLeft: 'auto', opacity: valid ? 1 : 0.5 }} onClick={() => onSave(d)}>
            <Icon name="check" size={12}/> Save KPI
          </button>
        </div>
      </div>
    </div>
  );
}

window.CustomKPIs = CustomKPIs;
window.KPI_UNITS = KPI_UNITS;
window.KPIEditor = KPIEditor;
window.KPI_SOURCES = KPI_SOURCES;
window.DEFAULT_KPIS = DEFAULT_KPIS;
window.kpiMonthsForRange = monthsForRange;
