// My Permits & Applications — single filterable table view.
// Columns: Number · Type · Municipality · Address · Status.
// Filters are per-column dropdowns opened from the header caret. Search is global.

function ApplicationsPage() {
  const t = window.tokens;
  const [account] = useActiveAccount();

  const params = new URLSearchParams(window.location.search);
  const [search, setSearch] = React.useState('');
  const [filters, setFilters] = React.useState({
    type: [],
    muni: params.get('muni') ? [params.get('muni')] : [],
    property: params.get('property') ? [params.get('property')] : [],
    status: [],
  });
  const [openMenu, setOpenMenu] = React.useState(null); // 'type' | 'muni' | ...

  React.useEffect(() => {
    setFilters({ type: [], muni: [], property: [], status: [] });
  }, [account]);

  // Synthesize an "updated" date per row based on its position in the data
  // (rows are ordered by recency within each account). Anchor: today.
  const TODAY = new Date(2026, 6, 2); // July 2, 2026
  const toTitleCase = (s) => s.replace(/\b([a-z])([a-z]*)/gi, (_, a, b) => a.toUpperCase() + b.toLowerCase());
  const rawRows = APPS[account].map((a, i) => {
    const d = new Date(TODAY);
    d.setDate(d.getDate() - i * 3 - (i % 2));
    return {
      ...a,
      statusLabel: a.bucket === 'draft' ? 'Draft' : toTitleCase(a.status),
      updatedAt: d,
    };
  });

  const filtered = rawRows.filter(a => {
    if (filters.type.length     && !filters.type.includes(a.type))            return false;
    if (filters.muni.length     && !filters.muni.includes(a.muni))            return false;
    if (filters.property.length && !filters.property.includes(a.property))    return false;
    if (filters.status.length   && !filters.status.includes(a.statusLabel))   return false;
    if (search) {
      const q = search.toLowerCase();
      if (
        !a.code.toLowerCase().includes(q) &&
        !a.type.toLowerCase().includes(q) &&
        !a.property.toLowerCase().includes(q) &&
        !a.muni.toLowerCase().includes(q) &&
        !a.statusLabel.toLowerCase().includes(q)
      ) return false;
    }
    return true;
  }).sort((a, b) => b.updatedAt - a.updatedAt);

  const uniq  = (key) => [...new Set(rawRows.map(a => a[key]))].sort();
  const opts  = {
    type:     uniq('type'),
    muni:     uniq('muni'),
    property: uniq('property'),
    status:   uniq('statusLabel'),
  };

  const toggle = (col, val) => setFilters(f => ({
    ...f,
    [col]: f[col].includes(val) ? f[col].filter(v => v !== val) : [...f[col], val],
  }));
  const clearCol = (col) => setFilters(f => ({ ...f, [col]: [] }));
  const clearAll = () => setFilters({ type: [], muni: [], property: [], status: [] });
  const activeFilterCount = Object.values(filters).reduce((n, arr) => n + arr.length, 0);

  return (
    <AccountPage activeNav="applications">
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 24, marginBottom: 32 }}>
        <div style={{ fontSize: 32, fontWeight: 500, letterSpacing: -0.5, color: t.color.text, lineHeight: 1.1 }}>
          My Permits &amp; Applications
        </div>
      </div>

      {/* Search + summary — no card wrapper */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 16 }}>
        <div style={{ position: 'relative', width: '33.333%', flexShrink: 0 }}>
          <FluentIcon name="search" size={16} style={{
            color: t.color.muted, position: 'absolute', left: 14, top: '50%',
            transform: 'translateY(-50%)', pointerEvents: 'none', zIndex: 1,
          }} />
          <input
            className="cm-input"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search"
            style={{
              width: '100%',
              background: t.color.bg,
              border: `1px solid ${t.color.strong}`,
              borderRadius: t.radius.xs,
              padding: '10px 14px 10px 40px',
              fontSize: 15,
              fontFamily: t.font.sans,
              color: t.color.text,
              outline: 'none',
            }}
          />
        </div>
        <div style={{ fontSize: 13, color: t.color.muted }}>
          Showing {filtered.length} of {rawRows.length}
          {activeFilterCount > 0 && (
            <>
              {' '}
              <button onClick={clearAll} style={{
                border: 'none', background: 'none', padding: 0, cursor: 'pointer',
                color: t.color.action, fontSize: 13, fontWeight: 400, fontFamily: t.font.sans,
                textDecoration: 'underline', textUnderlineOffset: 2,
                marginLeft: 6,
              }}>Clear Filters</button>
            </>
          )}
        </div>
      </div>

      <AppsTable
        rows={filtered}
        opts={opts}
        filters={filters}
        openMenu={openMenu}
        setOpenMenu={setOpenMenu}
        toggle={toggle}
        clearCol={clearCol}
      />
    </AccountPage>
  );
}

// ─── Table ─────────────────────────────────────────────────

const COLUMNS = [
  { key: 'code',        label: 'Number',       width: '160px', filterKey: null,        mono: true },
  { key: 'type',        label: 'Type',         width: '1.4fr', filterKey: 'type' },
  { key: 'muni',        label: 'Municipality', width: '1fr',   filterKey: 'muni' },
  { key: 'property',    label: 'Address',      width: '1.2fr', filterKey: 'property' },
  { key: 'statusLabel', label: 'Status',       width: '1fr',   filterKey: 'status', isStatus: true },
  { key: 'updatedAt',   label: 'Updated',      width: '140px', filterKey: null },
];

const DATE_FMT = new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric', year: 'numeric' });

function AppsTable({ rows, opts, filters, openMenu, setOpenMenu, toggle, clearCol }) {
  const t = window.tokens;
  const gridTemplate = COLUMNS.map(c => c.width).join(' ');

  return (
    <div style={{ border: `1px solid ${t.color.hair}`, borderRadius: 4, background: t.color.bg, overflow: 'visible' }}>
      {/* Header */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: gridTemplate,
        padding: '10px 18px',
        background: 'transparent',
        borderBottom: `1px solid ${t.color.hair}`,
        borderTopLeftRadius: 4, borderTopRightRadius: 4,
      }}>
        {COLUMNS.map((c) => (
          <ColHeader
            key={c.key}
            column={c}
            options={c.filterKey ? opts[c.filterKey] : null}
            active={c.filterKey ? filters[c.filterKey] : []}
            open={c.filterKey ? openMenu === c.filterKey : false}
            onOpen={() => setOpenMenu(openMenu === c.filterKey ? null : c.filterKey)}
            onClose={() => setOpenMenu(null)}
            onToggle={(v) => toggle(c.filterKey, v)}
            onClear={() => clearCol(c.filterKey)}
          />
        ))}
      </div>

      {/* Rows */}
      {rows.length === 0 ? (
        <div style={{ padding: '40px 18px', textAlign: 'center', color: t.color.muted, fontSize: 14 }}>
          No applications match these filters.
        </div>
      ) : rows.map((r, i) => (
        <a href="#" key={r.code + i} style={{
          display: 'grid',
          gridTemplateColumns: gridTemplate,
          padding: '14px 18px',
          borderBottom: i < rows.length - 1 ? `1px solid ${t.color.hair}` : 'none',
          alignItems: 'center',
          fontSize: 14,
          color: t.color.text,
          textDecoration: 'none',
          transition: 'background .12s',
        }}
          onMouseEnter={(e) => e.currentTarget.style.background = t.color.surfaceLo}
          onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
        >
          <div style={{ fontFamily: t.font.mono, fontSize: 12.5, color: t.color.muted }}>{r.code}</div>
          <div style={{ color: t.color.text, fontWeight: 500 }}>{r.type}</div>
          <div style={{ color: t.color.body }}>{r.muni}</div>
          <div style={{ color: t.color.body }}>{r.property}</div>
          <div><StatusPill row={r} /></div>
          <div style={{ color: t.color.body, fontVariantNumeric: 'tabular-nums' }}>{DATE_FMT.format(r.updatedAt)}</div>
        </a>
      ))}
    </div>
  );
}

function ColHeader({ column, options, active, open, onOpen, onClose, onToggle, onClear }) {
  const t = window.tokens;
  const ref = React.useRef(null);
  const filterable = !!column.filterKey;
  const hasActive = active && active.length > 0;

  React.useEffect(() => {
    if (!open) return;
    const off = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose(); };
    document.addEventListener('mousedown', off);
    return () => document.removeEventListener('mousedown', off);
  }, [open]);

  const labelStyle = {
    display: 'inline-flex', alignItems: 'center', gap: 6,
    fontSize: 11, fontWeight: 500, textTransform: 'uppercase',
    letterSpacing: 1.2, color: (hasActive || open) ? t.color.text : t.color.muted,
    fontFamily: t.font.mono,
    padding: filterable ? '4px 6px' : '4px 0',
    marginLeft: filterable ? -6 : 0,
    border: 'none', background: open ? t.color.surfaceHi : 'transparent',
    borderRadius: t.radius.xs, cursor: filterable ? 'pointer' : 'default',
  };

  if (!filterable) {
    return <div style={labelStyle}>{column.label}</div>;
  }

  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button onClick={onOpen} style={labelStyle}
        onMouseEnter={(e) => { if (!open) e.currentTarget.style.background = t.color.surfaceHi; }}
        onMouseLeave={(e) => { if (!open) e.currentTarget.style.background = 'transparent'; }}
      >
        {column.label}
        {hasActive && (
          <span style={{
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            minWidth: 16, height: 16, padding: '0 4px', borderRadius: 8,
            background: t.color.action, color: '#fff', fontSize: 10, fontWeight: 600,
            fontFamily: t.font.sans, lineHeight: 1,
          }}>{active.length}</span>
        )}
        <FluentIcon name="chevron_down" size={12} style={{ color: 'currentColor' }} />
      </button>

      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 4px)', left: 0,
          minWidth: 220, maxHeight: 320,
          display: 'flex', flexDirection: 'column',
          background: t.color.bg,
          border: `1px solid ${t.color.hair}`,
          borderRadius: t.radius.md,
          boxShadow: t.shadow.pop,
          zIndex: 40,
          overflow: 'hidden',
        }}>
          <div style={{ padding: 4, overflowY: 'auto', flex: 1, minHeight: 0 }}>
            {options.map(opt => {
              const checked = active.includes(opt);
              return (
                <div key={opt}
                  onClick={() => onToggle(opt)}
                  style={{
                    display: 'flex', alignItems: 'center',
                    padding: '7px 10px', borderRadius: t.radius.sm,
                    cursor: 'pointer',
                  }}
                  onMouseEnter={(e) => e.currentTarget.style.background = t.color.surfaceLo}
                  onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
                >
                  <Checkbox size="sm" checked={checked} label={opt} onChange={() => onToggle(opt)} />
                </div>
              );
            })}
          </div>
          {hasActive && (
            <div style={{
              borderTop: `1px solid ${t.color.hair}`,
              padding: 4, background: t.color.bg, flexShrink: 0,
            }}>
              <button onClick={() => { onClear(); onClose(); }} style={{
                width: '100%', textAlign: 'left', padding: '8px 10px',
                border: 'none', background: 'transparent', cursor: 'pointer',
                borderRadius: t.radius.sm, color: t.color.action,
                fontSize: 13, fontWeight: 400, fontFamily: t.font.sans,
                textDecoration: 'underline', textUnderlineOffset: 2,
              }}>Clear Filter</button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// Map a row to a Pill tone based on its bucket / status meaning.
function StatusPill({ row }) {
  const label = row.statusLabel;
  let tone = 'neutral';
  if (row.bucket === 'action')       tone = 'warn';
  else if (row.bucket === 'active')  tone = 'info';
  else if (row.bucket === 'closed')  tone = 'neutral';
  else if (row.bucket === 'draft')   tone = 'neutral';
  // Overrides for a few specific status verbs
  const l = label.toLowerCase();
  if (l.includes('approved') || l.includes('completed')) tone = 'ok';
  if (l.includes('expired') || l.includes('failed'))     tone = 'err';
  return <Pill tone={tone}>{label}</Pill>;
}

const applicationsRoot = ReactDOM.createRoot(document.getElementById('root'));
applicationsRoot.render(<ApplicationsPage />);
