// Dashboard page
// Exports: Dashboard

function DashExportBtn({ tickets, filename }) {
  const [exporting, setExporting] = React.useState(false);
  async function handleExport() {
    setExporting(true);
    try {
      await window.exportTicketsToExcel(tickets, filename);
    } catch (e) { console.error('Export failed:', e); alert('Export failed — please try again.'); }
    finally { setExporting(false); }
  }
  return (
    <button onClick={handleExport} disabled={exporting}
      title="Export to Excel"
      onMouseEnter={e => { if (!exporting) e.currentTarget.style.background = '#F0FDF4'; e.currentTarget.style.borderColor = '#16A34A'; }}
      onMouseLeave={e => { e.currentTarget.style.background = '#fff'; e.currentTarget.style.borderColor = '#E2E8F0'; }}
      style={{
        display: 'flex', alignItems: 'center', gap: 6,
        padding: '6px 12px', borderRadius: 7,
        border: '1.5px solid #E2E8F0', background: '#fff',
        fontSize: 12, fontWeight: 600, color: exporting ? '#94A3B8' : '#15803D',
        cursor: exporting ? 'wait' : 'pointer', fontFamily: 'inherit',
        transition: 'all 0.15s', whiteSpace: 'nowrap',
      }}>
      <IC name="download" size={13} color={exporting ? '#94A3B8' : '#16A34A'} />
      {exporting ? 'Exporting…' : 'Export'}
    </button>
  );
}

function StatCard({ label, value, sub, iconName, iconColor, iconBg, onClick }) {
  const [hov, setHov] = React.useState(false);
  return (
    <div onClick={onClick}
      onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}
      style={{
        background: '#fff', borderRadius: 12, padding: '20px 22px',
        border: '1.5px solid #E2E8F0', cursor: onClick ? 'pointer' : 'default',
        boxShadow: hov ? '0 4px 20px rgba(0,0,0,0.07)' : '0 1px 4px rgba(0,0,0,0.04)',
        transition: 'all 0.18s', transform: hov ? 'translateY(-1px)' : 'none',
        display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between',
      }}>
      <div>
        <div style={{ fontSize: 12, fontWeight: 600, color: '#94A3B8', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 8 }}>{label}</div>
        <div style={{ fontSize: 32, fontWeight: 800, color: '#0F172A', lineHeight: 1 }}>{value}</div>
        {sub && <div style={{ fontSize: 12, color: '#64748B', marginTop: 6 }}>{sub}</div>}
      </div>
      <div style={{ width: 42, height: 42, borderRadius: 10, background: iconBg, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
        <IC name={iconName} size={20} color={iconColor} />
      </div>
    </div>
  );
}

function MiniDonut({ data }) {
  const total = data.reduce((a, b) => a + b.value, 0);
  if (!total) return null;
  const R = 36, cx = 44, cy = 44, stroke = 12;
  const circ = 2 * Math.PI * R;
  let cumulativeLen = 0;
  const arcs = data.map(d => {
    const pct = d.value / total;
    const visible = circ * pct;
    const arc = { ...d, visible, gap: circ - visible, offset: -cumulativeLen, pct };
    cumulativeLen += visible;
    return arc;
  });
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>
      <svg width={88} height={88}>
        <circle cx={cx} cy={cy} r={R} fill="none" stroke="#F1F5F9" strokeWidth={stroke} />
        {arcs.map((arc, i) => (
          <circle key={i} cx={cx} cy={cy} r={R} fill="none"
            stroke={arc.color} strokeWidth={stroke}
            strokeDasharray={`${arc.visible} ${arc.gap}`}
            strokeDashoffset={arc.offset}
            style={{ transform: 'rotate(-90deg)', transformOrigin: `${cx}px ${cy}px` }} />
        ))}
        <text x={cx} y={cy + 5} textAnchor="middle" fontSize={15} fontWeight={800} fill="#0F172A">{total}</text>
      </svg>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        {data.map((d, i) => (
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
            <span style={{ width: 8, height: 8, borderRadius: 2, background: d.color, display: 'inline-block', flexShrink: 0 }} />
            <span style={{ fontSize: 12, color: '#64748B' }}>{d.label}</span>
            <span style={{ fontSize: 12, fontWeight: 700, color: '#334155', marginLeft: 2 }}>{d.value}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function Dashboard({ tickets, onNav, isAdmin, onRefresh }) {
  const isMobile = useIsMobile();
  // the dashboard sits beside a 220px sidebar, so it needs its own, later breakpoints
  const [vw, setVw] = React.useState(window.innerWidth);
  React.useEffect(() => { const f = () => setVw(window.innerWidth); window.addEventListener('resize', f); return () => window.removeEventListener('resize', f); }, []);
  const compact = vw < 1000, stackMain = vw < 1180;
  const open       = tickets.filter(t => t.status === 'Open').length;
  const inProgress = tickets.filter(t => t.status === 'In Progress').length;
  const resolved   = tickets.filter(t => t.status === 'Resolved').length;
  const urgent     = tickets.filter(t => t.priority === 'Urgent' && t.status === 'Open').length;

  const { categories } = window.MOCK;
  const visibleCats = categories.filter(c => isAdmin || !c.adminOnly);

  const [catFilter,    setCatFilter]    = React.useState('all');
  const [statusFilter, setStatusFilter] = React.useState('all');
  const [sortCol, setSortCol] = React.useState('status');
  const [sortDir, setSortDir] = React.useState('asc');
  const [ticketToDelete, setTicketToDelete] = React.useState(null);
  const [dashDeleting,   setDashDeleting]   = React.useState(false);

  async function handleDashDelete() {
    if (!ticketToDelete) return;
    setDashDeleting(true);
    try {
      await fetch(`/api/tickets/${ticketToDelete.dbId}`, {
        method: 'DELETE',
        headers: { Authorization: 'Bearer ' + (localStorage.getItem('hub_token') || '') },
      });
      setTicketToDelete(null);
      if (onRefresh) onRefresh();
    } catch (e) { console.error(e); }
    finally { setDashDeleting(false); }
  }

  const STATUS_RANK   = { 'Open': 0, 'In Progress': 1, 'Resolved': 2, 'Closed': 3 };
  const PRIORITY_RANK = { 'Urgent': 0, 'High': 1, 'Medium': 2, 'Low': 3 };

  function handleSort(col) {
    if (sortCol === col) setSortDir(d => d === 'asc' ? 'desc' : 'asc');
    else { setSortCol(col); setSortDir('asc'); }
  }

  const filtered = tickets.filter(t =>
    (catFilter    === 'all' || t.categoryId === catFilter) &&
    (statusFilter === 'all' || t.status     === statusFilter)
  );

  const sorted = [...filtered].sort((a, b) => {
    const dir = sortDir === 'asc' ? 1 : -1;
    if (sortCol === 'concern')  return dir * a.title.localeCompare(b.title);
    if (sortCol === 'priority') return dir * ((PRIORITY_RANK[a.priority] ?? 99) - (PRIORITY_RANK[b.priority] ?? 99));
    if (sortCol === 'status')   return dir * ((STATUS_RANK[a.status] ?? 99) - (STATUS_RANK[b.status] ?? 99));
    if (sortCol === 'by')       return dir * (a.submittedBy?.name || '').localeCompare(b.submittedBy?.name || '');
    if (sortCol === 'date')     return dir * String(b.updatedAt).localeCompare(String(a.updatedAt));
    return 0;
  });

  const recent = sorted.slice(0, 8);

  const isAgent = window._synUser?.role === 'agent';

  // For agents the category breakdown is useless (they only see one category).
  // Show a status breakdown of their queue instead.
  const donutData = isAgent
    ? [
        { label: 'Open',        color: '#2563EB', value: tickets.filter(t => t.status === 'Open').length },
        { label: 'In Progress', color: '#B45309', value: tickets.filter(t => t.status === 'In Progress').length },
        { label: 'Resolved',    color: '#10B981', value: tickets.filter(t => t.status === 'Resolved').length },
        { label: 'Closed',      color: '#94A3B8', value: tickets.filter(t => t.status === 'Closed').length },
      ].filter(d => d.value > 0)
    : categories.filter(c => !c.adminOnly).map(c => ({
        label: c.label.replace(' Issues', '').replace(' Tracking', ' Track.'),
        color: c.color,
        value: tickets.filter(t => t.categoryId === c.id && (t.status === 'Open' || t.status === 'In Progress')).length,
      })).filter(d => d.value > 0);

  const donutTitle = isAgent ? 'My Queue by Status' : 'Active by Type';

  const timed = tickets.filter(t => t.workSeconds > 0);
  const timeTotal = timed.reduce((a, t) => a + t.workSeconds, 0), timeCount = timed.length;
  const finished = timed.filter(t => t.status === 'Resolved' || t.status === 'Closed');
  const timeDone = finished.length, timeTotalDone = finished.reduce((a, t) => a + t.workSeconds, 0);

  const hour = new Date().getHours();
  const greeting = hour < 12 ? 'Good morning' : hour < 17 ? 'Good afternoon' : 'Good evening';
  const DelModal = window.DeleteConfirmModal;

  return (
    <div>
      {/* Greeting */}
      <div style={{ marginBottom: 24 }}>
        <h1 style={{ fontSize: 24, fontWeight: 800, color: '#0F172A', margin: 0 }}>{greeting}</h1>
        <p style={{ color: '#64748B', marginTop: 4, fontSize: 14 }}>
          {window._synUser?.role === 'admin'
            ? "Here's an overview of all concerns today"
            : window._synUser?.role === 'agent'
            ? "Here's what's happening in your team's queue"
            : "Here's a quick look at your concerns"
          } — {new Date().toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' })}
        </p>
      </div>

      {/* Stats row */}
      <div style={{ display: 'grid', gridTemplateColumns: compact ? 'repeat(2, 1fr)' : 'repeat(4, 1fr)', gap: isMobile ? 12 : 16, marginBottom: 24 }}>
        <StatCard label="Open Concerns"   value={open}       sub="Awaiting action"        iconName="inbox"   iconColor="#2563EB" iconBg="#EFF6FF" onClick={() => onNav('my_tickets')} />
        <StatCard label="In Progress"     value={inProgress} sub="Being worked on"        iconName="clock"   iconColor="#B45309" iconBg="#FFFBEB" />
        <StatCard label="Resolved"        value={resolved}   sub="Closed successfully"    iconName="check"   iconColor="#065F46" iconBg="#ECFDF5" />
        <StatCard label="Urgent"          value={urgent}     sub="Need immediate action"  iconName="alert"   iconColor="#B91C1C" iconBg="#FEF2F2" />
      </div>

      {/* Time worked: the hours developers have put in, counted from In Progress to Resolved */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: isMobile ? 12 : 16, marginBottom: 24 }}>
        <StatCard label="Time Worked"        value={window.fmtDuration(timeTotal)} sub={timeCount + ' concern' + (timeCount === 1 ? '' : 's') + ' with time logged'} iconName="clock" iconColor="#1A5090" iconBg="#EAF1FA" />
        <StatCard label="Avg Time to Resolve" value={timeDone ? window.fmtDuration(timeTotalDone / timeDone) : '—'} sub={timeDone ? 'Across ' + timeDone + ' finished concern' + (timeDone === 1 ? '' : 's') : 'No finished concerns yet'} iconName="check" iconColor="#065F46" iconBg="#ECFDF5" />
      </div>

      {/* Main grid */}
      <div style={{ display: 'grid', gridTemplateColumns: stackMain ? '1fr' : '1fr 320px', gap: 20, alignItems: 'start' }}>
        {/* Recent Tickets */}
        <div style={{ background: '#fff', borderRadius: 12, border: '1.5px solid #E2E8F0', overflow: 'hidden' }}>
          <div style={{ padding: isMobile ? '14px 16px' : '18px 22px', borderBottom: '1px solid #F1F5F9', display: 'flex', alignItems: isMobile ? 'flex-start' : 'center', flexDirection: isMobile ? 'column' : 'row', justifyContent: 'space-between', gap: isMobile ? 10 : 12 }}>
            <div>
              <div style={{ fontWeight: 700, color: '#0F172A', fontSize: 15 }}>Recent Concerns</div>
              <div style={{ fontSize: 12, color: '#94A3B8', marginTop: 2 }}>
                {filtered.length === 0
                  ? 'No matching concerns'
                  : `Showing ${recent.length} of ${filtered.length} — actionable first`}
              </div>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
              {/* Status dropdown */}
              <select
                value={statusFilter}
                onChange={e => setStatusFilter(e.target.value)}
                style={{
                  padding: '6px 12px', borderRadius: 7, border: '1.5px solid #E2E8F0',
                  fontSize: 13, fontFamily: 'inherit', color: '#374151',
                  background: '#fff', cursor: 'pointer', outline: 'none',
                }}>
                <option value="all">All Statuses</option>
                <option value="Open">Open</option>
                <option value="In Progress">In Progress</option>
                <option value="Resolved">Resolved</option>
                <option value="Closed">Closed</option>
              </select>
              {/* Category dropdown — hidden for agents since they only see one category */}
              {!isAgent && (
                <select
                  value={catFilter}
                  onChange={e => setCatFilter(e.target.value)}
                  style={{
                    padding: '6px 12px', borderRadius: 7, border: '1.5px solid #E2E8F0',
                    fontSize: 13, fontFamily: 'inherit', color: '#374151',
                    background: '#fff', cursor: 'pointer', outline: 'none',
                  }}>
                  <option value="all">All Types</option>
                  {visibleCats.map(c => <option key={c.id} value={c.id}>{c.label}</option>)}
                </select>
              )}
              <DashExportBtn tickets={tickets} filename="dashboard-concerns" />
              <button onClick={() => onNav('my_tickets')} style={{
                fontSize: 12, fontWeight: 600, color: BRAND_ORANGE, background: 'none',
                border: 'none', cursor: 'pointer', fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 4,
                whiteSpace: 'nowrap',
              }}>View all <IC name="chevron_r" size={12} color={BRAND_ORANGE} /></button>
            </div>
          </div>
          <div style={{ overflowX: 'auto' }}>
          {/* Column headers — sortable */}
          <div style={{
            display: compact ? 'none' : 'grid', gridTemplateColumns: isAdmin ? '12px minmax(0, 1fr) 80px 120px 160px 92px 30px' : '12px minmax(0, 1fr) 80px 120px 160px 92px',
            gap: 18, padding: '10px 22px',
            background: '#F8FAFC', borderBottom: '1px solid #F1F5F9',
            minWidth: 680,
          }}>
            {[
              { label: '',         col: null },
              { label: 'Concern',  col: 'concern' },
              { label: 'Priority', col: 'priority' },
              { label: 'Status',   col: 'status' },
              { label: 'By',       col: 'by' },
              { label: 'Date',     col: 'date' },
            ].map(({ label, col }, i) => (
              <span key={i} onClick={col ? () => handleSort(col) : undefined} style={{
                fontSize: 11, fontWeight: 800,
                color: sortCol === col ? '#1A5090' : '#94A3B8',
                textTransform: 'uppercase', letterSpacing: '0.06em',
                cursor: col ? 'pointer' : 'default', userSelect: 'none',
                display: 'flex', alignItems: 'center', gap: 3,
                justifyContent: i === 5 ? 'flex-end' : 'flex-start',
              }}>
                {label}
                {col && sortCol === col && <span style={{ fontSize: 9 }}>{sortDir === 'asc' ? '▲' : '▼'}</span>}
              </span>
            ))}
            {isAdmin && <span />}
          </div>
          <div>
            {recent.length === 0 ? (
              <div style={{ padding: '32px 22px', textAlign: 'center', color: '#CBD5E1', fontSize: 13 }}>No concerns found</div>
            ) : recent.map((t, i) => {
              const cat = window.MOCK.categories.find(c => c.id === t.categoryId);
              if (compact) return (
                <div key={t.id} onClick={() => onNav('ticket_detail', t)}
                  onMouseEnter={e => e.currentTarget.style.background = '#FAFBFF'}
                  onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
                  style={{
                    padding: '12px 16px',
                    borderBottom: i < recent.length - 1 ? '1px solid #F1F5F9' : 'none',
                    cursor: 'pointer', transition: 'background 0.12s',
                  }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 10, marginBottom: 8 }}>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 15, fontWeight: 700, color: '#1E293B', marginBottom: 6 }}>{t.title}</div>
                      <div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: '5px 8px' }}>
                        <span style={{ width: 7, height: 7, borderRadius: '50%', background: cat?.color || '#94A3B8', display: 'inline-block', flexShrink: 0 }} />
                        <span style={{ fontSize: 12, color: '#94A3B8', fontFamily: 'monospace', whiteSpace: 'nowrap' }}>{t.id}</span>
                        <span style={{ fontSize: 12, color: '#CBD5E1' }}>·</span>
                        <span style={{ fontSize: 12, color: cat?.color, fontWeight: 700 }}>{cat?.label}</span>
                      {t.clientName && window._synUser?.role !== 'client' && (
                        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 12.5, fontWeight: 700, color: '#475569', background: '#F1F5F9', padding: '2px 11px 2px 3px', borderRadius: 999, whiteSpace: 'nowrap' }}>
                          <ClientLogo clientId={t.clientId} name={t.clientName} hasLogo={t.clientHasLogo} version={t.clientLogoVer} size={24} radius={12} />{t.clientName}
                        </span>
                      )}
                      </div>
                    </div>
                    <StatusBadge status={t.status} />
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                    <PriorityBadge priority={t.priority} />
                    <span style={{ fontSize: 12.5, color: '#94A3B8' }}>{t.createdAt}</span>
                  </div>
                </div>
              );
              return (
                <div key={t.id} onClick={() => onNav('ticket_detail', t)}
                  onMouseEnter={e => e.currentTarget.style.background = '#FAFBFF'}
                  onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
                  style={{
                    display: 'grid',
                    gridTemplateColumns: isAdmin ? '12px minmax(0, 1fr) 80px 120px 160px 92px 30px' : '12px minmax(0, 1fr) 80px 120px 160px 92px',
                    alignItems: 'center', gap: 18,
                    padding: '15px 22px', minWidth: 680,
                    borderBottom: i < recent.length - 1 ? '1px solid #F8FAFC' : 'none',
                    cursor: 'pointer', transition: 'background 0.12s',
                  }}>
                  <div style={{ width: 8, height: 8, borderRadius: '50%', background: cat?.color || '#94A3B8', justifySelf: 'center' }} />
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 15, fontWeight: 700, color: '#1E293B', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{t.title}</div>
                    <div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: '5px 8px', marginTop: 4 }}>
                      <span style={{ fontSize: 12, color: '#94A3B8', fontFamily: 'monospace', whiteSpace: 'nowrap' }}>{t.id}</span>
                      <span style={{ fontSize: 12, color: '#CBD5E1' }}>·</span>
                      <span style={{ fontSize: 12, color: cat?.color, fontWeight: 700 }}>{cat?.label}</span>
                      {t.clientName && window._synUser?.role !== 'client' && (
                        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 12.5, fontWeight: 700, color: '#475569', background: '#F1F5F9', padding: '2px 11px 2px 3px', borderRadius: 999, whiteSpace: 'nowrap' }}>
                          <ClientLogo clientId={t.clientId} name={t.clientName} hasLogo={t.clientHasLogo} version={t.clientLogoVer} size={24} radius={12} />{t.clientName}
                        </span>
                      )}
                                          </div>
                  </div>
                  <div style={{ display: 'flex' }}><PriorityBadge priority={t.priority} /></div>
                  <div style={{ display: 'flex' }}><StatusBadge status={t.status} /></div>
                  <div title={'Raised by ' + t.submittedBy.name} style={{ display: 'flex', alignItems: 'center', gap: 9, minWidth: 0 }}><Avatar name={t.submittedBy.name} initials={t.submittedBy.initials} size={32} /><span style={{ fontSize: 13, fontWeight: 600, color: '#475569', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{t.submittedBy.name}</span></div>
                  <span style={{ fontSize: 12.5, color: '#64748B', textAlign: 'right', whiteSpace: 'nowrap' }}>{t.createdAt}</span>
                  {isAdmin && (
                    <button
                      onClick={e => { e.stopPropagation(); setTicketToDelete(t); }}
                      title="Delete concern"
                      onMouseEnter={e => e.currentTarget.style.color = '#DC2626'}
                      onMouseLeave={e => e.currentTarget.style.color = '#CBD5E1'}
                      style={{
                        background: 'none', border: 'none', cursor: 'pointer', padding: 4,
                        display: 'flex', alignItems: 'center', justifyContent: 'center',
                        borderRadius: 6, color: '#CBD5E1', transition: 'color 0.12s',
                      }}>
                      <IC name="trash" size={14} color="currentColor" />
                    </button>
                  )}
                </div>
              );
            })}
          </div>
          </div>{/* end overflowX scroll wrapper */}
        </div>

        {/* Right column */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          {/* Category breakdown */}
          <div style={{ background: '#fff', borderRadius: 12, border: '1.5px solid #E2E8F0', padding: '18px 20px' }}>
            <div style={{ fontWeight: 700, color: '#0F172A', fontSize: 14, marginBottom: 14 }}>{donutTitle}</div>
            <MiniDonut data={donutData} />
          </div>

          {/* Quick Submit */}
          {(
          <div style={{ background: '#fff', borderRadius: 12, border: '1.5px solid #E2E8F0', padding: '18px 20px' }}>
            <div style={{ fontWeight: 700, color: '#0F172A', fontSize: 14, marginBottom: 12 }}>Quick Submit</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {window.MOCK.categories.filter(c => isAdmin || !c.adminOnly).map(cat => (
                <button key={cat.id} onClick={() => onNav('submit', { categoryId: cat.id })} style={{
                  display: 'flex', alignItems: 'center', gap: 10, padding: '9px 12px',
                  background: cat.bg, border: 'none', borderRadius: 8, cursor: 'pointer',
                  fontFamily: 'inherit', transition: 'opacity 0.12s', textAlign: 'left',
                }}>
                  <span style={{ width: 8, height: 8, borderRadius: '50%', background: cat.color, flexShrink: 0 }} />
                  <span style={{ fontSize: 13, fontWeight: 600, color: '#1E293B' }}>{cat.label}</span>
                </button>
              ))}
            </div>
          </div>
          )}
        </div>
      </div>

      {ticketToDelete && DelModal && (
        <DelModal
          title="Delete Concern"
          message={`Permanently delete "${ticketToDelete.title}"? This cannot be undone.`}
          onConfirm={handleDashDelete}
          onCancel={() => setTicketToDelete(null)}
          loading={dashDeleting}
        />
      )}
    </div>
  );
}

Object.assign(window, { Dashboard });
