<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <title>Bellwether Consulting ERP</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
  <script crossorigin
    src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.23.5/babel.min.js"></script>
  <script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/recharts/2.12.0/Recharts.min.js"></script>
  <style>
    /* Compact status row under Description */
    .status-inline-row label {
      margin-right: 12px;
      font-size: 12px;
    }

    .status-inline-row input[type=checkbox] {
      vertical-align: middle;
    }

    /* Stack Status as its own row under each task */
    .status-header {
      display: none;
    }

    td.status-cell-row {
      display: block;
      width: 100%;
      padding-top: 6px;
      border-top: 0;
    }

    td.status-cell-row * {
      margin-right: 6px;
    }

    html,
    body {
      margin: 0;
      font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial, "Noto Sans";
      color: #0f172a;
      background: #ffffff;
    }

    button,
    select,
    input,
    textarea {
      font: inherit;
    }

    table {
      border-spacing: 0;
    }

    .clamp-2 {
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }

    /* sticky shell that shrinks on scroll */
    .sticky-shell {
      position: sticky;
      top: 0;
      z-index: 30;
      /* give the header a soft gradient to make it stand out */
      background: #ffffff;
      box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06)
    }

    .sticky-inner {
      transition: transform .2s ease, padding .2s ease
    }

    /* Auto-hide menu styles */
    .menu-collapsible {
      transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
      max-height: 500px;
      opacity: 1;
      transform: translateY(0);
      overflow: visible;
    }

    .menu-collapsible.hidden {
      max-height: 0;
      opacity: 0;
      transform: translateY(-20px);
      pointer-events: none;
      margin-bottom: 0 !important;
    }

    .hover-trigger-zone {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      height: 20px;
      z-index: 100;
      /* background: rgba(255,0,0,0.1);  Debug visualization */
    }

    .reveal-indicator {
      position: fixed;
      top: 0;
      left: 50%;
      transform: translateX(-50%);
      background: #3b82f6;
      color: white;
      padding: 2px 15px;
      border-bottom-left-radius: 10px;
      border-bottom-right-radius: 10px;
      font-size: 14px;
      z-index: 99;
      cursor: pointer;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      transition: all 0.3s ease;
      opacity: 0;
      pointer-events: none;
    }

    .reveal-indicator.visible {
      opacity: 1;
      pointer-events: auto;
    }

    .reveal-indicator:hover {
      padding-bottom: 8px;
      background: #2563eb;
    }

    /* New styles for improved UI */
    .header-compact {
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: wrap;
      gap: 10px;
    }

    .title-section {
      display: flex;
      align-items: baseline;
      gap: 12px;
      flex-wrap: wrap;
    }

    .user-section {
      display: flex;
      align-items: center;
      gap: 8px;
      flex-wrap: wrap;
    }

    .tile-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
      gap: 6px;
      margin-top: 8px;
    }

    .date-input-compact {
      width: 90px !important;
    }

    .subtask-date-grid {
      display: grid;
      grid-template-columns: auto 1fr 180px 140px 100px 100px auto;
      gap: 6px;
      align-items: center;
    }

    .calendar-day {
      min-height: 80px;
      width: 100%;
      position: relative;
    }

    .calendar-task-list {
      margin: 0;
      padding-left: 16px;
      font-size: 11px;
    }

    .confirmation-modal {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(0, 0, 0, 0.5);
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 100;
    }

    .confirmation-content {
      background: white;
      padding: 20px;
      border-radius: 10px;
      text-align: center;
    }

    .recurrence-options {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 10px;
      margin-top: 10px;
    }

    /* === UI tweaks (2025-09-08) === */
    .table-wrapper {
      overflow-x: scroll;
    }

    /* always show horizontal scrollbar */
    .table-wrapper::-webkit-scrollbar {
      height: 10px;
    }

    .table-wrapper::-webkit-scrollbar-thumb {
      background: #cbd5e1;
      border-radius: 5px;
    }

    .table-wrapper::-webkit-scrollbar-track {
      background: #f1f5f9;
    }

    /* Force white background only for the main table inside the wrapper */
    .table-wrapper table {
      background: #ffffff;
    }

    /* Description cell: narrower with wrapping */
    .description-cell {
      max-width: 250px;
      white-space: normal;
      word-wrap: break-word;
    }

    .clamp-3 {
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }

    /* === UI tweaks (login/table/scroll) === */
    .table-wrapper {
      overflow-x: scroll;
    }

    .table-wrapper::-webkit-scrollbar {
      height: 10px;
    }

    .table-wrapper::-webkit-scrollbar-thumb {
      background: #cbd5e1;
      border-radius: 5px;
    }

    .table-wrapper::-webkit-scrollbar-track {
      background: #f1f5f9;
    }

    .table-wrapper table {
      background: #ffffff;
    }

    .description-cell {
      max-width: 250px;
      white-space: normal;
      word-wrap: break-word;
    }

    .clamp-3 {
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }

    @media (max-width: 640px) {
      .tile-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
      }
    }


    /* --- Modern Pill Style for Status Tiles (2025-10 Update) --- */
    .tile-grid button,
    .tile-grid div {
      border-radius: 999px !important;
      padding: 6px 14px !important;
      padding: 5px 12px !important;
      font-weight: 600;
      font-size: 13px;
      transition: all 0.18s ease-in-out;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12);
    }

    .tile-grid button:hover,
    .tile-grid div:hover {
      transform: scale(1.04);
      box-shadow: 0 3px 6px rgba(0, 0, 0, 0.18);
    }

    /* --- Slimmer filter boxes + Bellwether blue hover/focus --- */
    input,
    select {
      height: 26px !important;
      font-size: 13px !important;
      padding: 2px 6px !important;
      border-radius: 6px !important;
      transition: all 0.18s ease-in-out;
    }

    input:hover,
    select:hover,
    input:focus,
    select:focus {
      border-color: #0ea5e9 !important;
      box-shadow: 0 0 4px rgba(14, 165, 233, 0.4);
      outline: none;
    }

    label {
      margin-bottom: 2px !important;
    }

    /* ================= MODERN UI PATCH (SAFE) ================= */

    /* Buttons */
    button {
      border-radius: 999px !important;
      transition: all 0.2s ease;
    }

    button:hover {
      transform: translateY(-1px);
    }

    /* Tables */
    table tr:nth-child(even) {
      background: #f9fafb;
    }

    /* Table header sticky will be handled via Ghost Header in the sticky-shell */
    .table-wrapper table thead th {
      background: #f1f5f9;
      font-size: 11px;
      font-weight: 600;
      color: #64748b;
      text-transform: uppercase;
      white-space: nowrap;
      padding: 6px 4px;
    }

    .ghost-header-container {
      overflow: hidden;
      background: #f1f5f9;
      display: none;
      /* Shown via React state/logic */
      border-bottom: 1px solid #e2e8f0;
    }

    .ghost-header-container table {
      width: 100%;
      font-size: 13px;
      border-collapse: collapse;
      min-width: 900px;
    }

    /* MODAL FIX (critical) */
    .erp-modal-backdrop {
      position: fixed;
      inset: 0;
      background: rgba(15, 23, 42, 0.45);
      backdrop-filter: blur(4px);
      z-index: 9999;
      /* this is the key fix */
    }

    .erp-modal-box {
      background: #ffffff;
      border-radius: 14px;
      padding: 20px;
      width: 90%;
      max-width: 1000px;
      max-height: 90vh;
      overflow: auto;
      margin: 5vh auto;
      box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
    }
  </style>
  <script>
    /* Bridge server session -> ERP app login (localStorage) */
    (function () {
      function getCookie(name) {
        var m = document.cookie.match(new RegExp('(?:^|; )' + name.replace(/([.$?*|{}()[\]\\/+^])/g, '\\$1') + '=([^;]*)'));
        return m ? decodeURIComponent(m[1]) : '';
      }
      var serverUser = getCookie('erp_user');
      if (serverUser) { window.__HAS_SERVER_SESSION = true; }   // e.g. "Tax", "Audit", "Accounts", "Corporate", "Admin & HR", "Management"
      if (!serverUser) return;

      // (1) normalize to be safe (spaces/case)
      var key = serverUser.trim();

      // (2) Map server usernames -> seeded display names in your app
      var nameMap = {
        "Tax": "Tax Head",
        "Audit": "Audit Head",
        "Accounts": "Accounts Lead",
        "Corporate": "Corporate Head",
        "Admin & HR": "Admin & HR Head",
        "Management": "Arshad Saleem",  // default to Arshad; Aizaz can also sign in via "Aizaz"
        "Aizaz": "Aizaz",
        "Arshad": "Arshad Saleem",
        "CEO": "Arshad Saleem"
      };
      var wantName = nameMap[key] || key;

      function trySetLogin() {
        try {
          var raw = localStorage.getItem('bellwether_erp_v7_8_state');
          if (!raw) return false;
          var state = JSON.parse(raw);
          if (!state || !Array.isArray(state.users)) return false;
          var user = state.users.find(function (u) { return u.name === wantName; });
          if (!user || !user.id) return false;
          localStorage.setItem('bellwether_current_user_id', user.id);
          return true;
        } catch (e) { return false; }
      }

      if (!trySetLogin()) {
        var tries = 0;
        var t = setInterval(function () {
          if (trySetLogin() || ++tries > 20) clearInterval(t);
        }, 200);
      }
    })();
  </script>

</head>

<body>
  <div id="root">
    <div style="display: flex; justify-content: center; align-items: center; height: 100vh; flex-direction: column;">
      <h2>Bellwether ERP Loading...</h2>
      <p>If this message persists, there may be a JavaScript error.</p>
      <p>Please check the browser console for error details.</p>
    </div>
  </div>

  <script type="text/babel">




    // --- ERP Data Endpoints & Fallbacks (v10) ---
    if (typeof window.API_BASE === "undefined") window.API_BASE = "/erp/api.php";
    if (typeof window.API_KEY === "undefined") window.API_KEY = "bellwether-local";

    async function serverLoadState() {
      // 1) API (GET then POST)
      const apiURL = `${window.API_BASE}?op=load`;
      try {
        const res = await fetch(apiURL, { headers: { 'X-ERP-Key': window.API_KEY } });
        if (res.ok) {
          const data = await res.json();
          if (data && ((Array.isArray(data.tasks) && data.tasks.length) || (Array.isArray(data.clients) && data.clients.length))) {
            console.log('[ERP] Loaded via API GET', apiURL, { t: data.tasks?.length || 0, c: data.clients?.length || 0, u: data.users?.length || 0 });
            return data;
          }
        } else {
          console.warn('[ERP] API GET not ok', apiURL, res.status);
        }
      } catch (e) { console.warn('[ERP] API GET error', apiURL, e); }
      try {
        const resP = await fetch(apiURL, { method: 'POST', headers: { 'X-ERP-Key': window.API_KEY } });
        if (resP.ok) {
          const dataP = await resP.json();
          if (dataP && ((Array.isArray(dataP.tasks) && dataP.tasks.length) || (Array.isArray(dataP.clients) && dataP.clients.length))) {
            console.log('[ERP] Loaded via API POST', apiURL, { t: dataP.tasks?.length || 0, c: dataP.clients?.length || 0, u: dataP.users?.length || 0 });
            return dataP;
          }
        } else {
          console.warn('[ERP] API POST not ok', apiURL, resP.status);
        }
      } catch (e) { console.warn('[ERP] API POST error', apiURL, e); }

      // 2) Static JSON without querystring
      const jsonCandidates = ['./erp_data.json', '/erp/erp_data.json'];
      for (const u of jsonCandidates) {
        try {
          const r = await fetch(u, { cache: 'no-store' });
          if (r.ok) {
            const j = await r.json();
            if (j && (Array.isArray(j.tasks) || Array.isArray(j.clients) || Array.isArray(j.users))) {
              console.log('[ERP] Loaded via JSON', u, { t: j.tasks?.length || 0, c: j.clients?.length || 0, u: j.users?.length || 0 });
              return j;
            } else {
              console.warn('[ERP] JSON shape unexpected', u, j);
            }
          } else {
            console.warn('[ERP] JSON not ok', u, r.status);
          }
        } catch (e) { console.warn('[ERP] JSON fetch error', u, e); }
      }

      // 3) PHP reader (for hosts that deny .json)
      const phpCandidates = ['./erp_data.php', '/erp/erp_data.php'];
      for (const u of phpCandidates) {
        try {
          const r = await fetch(u, { cache: 'no-store' });
          if (r.ok) {
            const j = await r.json();
            if (j && (Array.isArray(j.tasks) || Array.isArray(j.clients) || Array.isArray(j.users))) {
              console.log('[ERP] Loaded via PHP JSON', u, { t: j.tasks?.length || 0, c: j.clients?.length || 0, u: j.users?.length || 0 });
              return j;
            }
          } else {
            console.warn('[ERP] PHP JSON not ok', u, r.status);
          }
        } catch (e) { console.warn('[ERP] PHP JSON error', u, e); }
      }

      // 4) JS global (for hosts that deny both .json and PHP routes)
      async function tryScript(u) {
        await new Promise((resolve, reject) => {
          const s = document.createElement('script');
          s.src = u + '?v=' + Date.now();
          s.onload = () => resolve();
          s.onerror = () => reject(new Error('script load failed'));
          document.head.appendChild(s);
        });
        if (window.__ERP_DATA && ((Array.isArray(window.__ERP_DATA.tasks) && window.__ERP_DATA.tasks.length) || (Array.isArray(window.__ERP_DATA.clients) && window.__ERP_DATA.clients.length))) {
          console.log('[ERP] Loaded via JS global', u, { t: window.__ERP_DATA.tasks?.length || 0, c: window.__ERP_DATA.clients?.length || 0, u: window.__ERP_DATA.users?.length || 0 });
          return window.__ERP_DATA;
        }
        return null;
      }
      for (const u of ['./erp_data.js', '/erp/erp_data.js']) {
        try {
          const out = await tryScript(u);
          if (out) return out;
        } catch (e) { console.warn('[ERP] JS global failed', u, e); }
      }

      console.warn('[ERP] All sources empty, using seed');
      return { tasks: [], clients: [], users: [] };
    }
    // --- End injection ---





    // Error boundary to catch and display errors
    class ErrorBoundary extends React.Component {
      constructor(props) {
        super(props);
        this.state = { hasError: false, error: null };
      }

      static getDerivedStateFromError(error) {
        return { hasError: true, error };
      }

      componentDidCatch(error, errorInfo) {
        console.error("ERP Error:", error, errorInfo);
      }

      render() {
        if (this.state.hasError) {
          return (
            <div style={{ padding: '20px', textAlign: 'center' }}>
              <h2>Something went wrong with the ERP system.</h2>
              <p>Please refresh the page or contact support if the issue persists.</p>
              <div style={{ textAlign: 'left', marginTop: '20px', overflowX: 'auto' }}>
                <h4>Error Details</h4>
                {/* Show full stack trace for debugging purposes */}
                <pre style={{ whiteSpace: 'pre-wrap', fontSize: 12, background: '#f9fafb', padding: 8, borderRadius: 4 }}>
                  {this.state.error?.stack || this.state.error?.toString()}
                </pre>
              </div>
            </div>
          );
        }

        return this.props.children;
      }
    }

    /**
     * Bellwether Consulting ERP – v7.8 (single-file, patched)
     * Fixes implemented based on the provided requirements
     */
    const { useMemo, useState, useEffect, useRef, useCallback } = React;

    // Destructure Recharts components safely
    const RechartsLib = window.Recharts || {
      BarChart: () => <div style={{ padding: 20, textAlign: 'center', color: '#64748b', background: '#f8fafc', borderRadius: 8 }}>Chart visualization not available (Library failed to load)</div>,
      Bar: () => null,
      XAxis: () => null,
      YAxis: () => null,
      Tooltip: () => null,
      Legend: () => null,
      ResponsiveContainer: ({ children }) => <div style={{ width: '100%', height: '100%' }}>{children}</div>,
      CartesianGrid: () => null,
      PieChart: () => null,
      Pie: () => null,
      Cell: () => null
    };
    const { BarChart, Bar, XAxis, YAxis, Tooltip, Legend, ResponsiveContainer, CartesianGrid, PieChart, Pie, Cell } = RechartsLib;

    /********************** PAID & BALANCE HELPERS (AUTO ADDED) **********************/
    const computeBalance = (t) => {
      const total = Number(t.invoice_amount) || 0;
      if (t.invoice_status === "Paid" || t.invoice_status === "N/A") return 0;
      const paid = Number(t.paid_amount) || 0;
      const bal = total - paid;
      return bal < 0 ? 0 : bal;
    };
    /*******************************************************************************/


    /* ============================ Constants & Helpers ============================ */
    const DEFAULT_ENUMS = {
      departments: ["Audit", "Tax", "Corporate", "Admin & HR", "Accounts", "Management"],
      // Updated statuses as per requirements
      taskStatus: ["Not Started", "Cancelled", "In Progress", "Completed", "Overdue"],
      // Include N/A for tasks where no invoicing is required
      invoiceStatus: ["Not Issued", "Issued", "Paid", "Unpaid", "Partially Paid", "N/A"],
      priority: ["Critical", "High", "Medium", "Low"],
      // Recurrence options
      recurrencePatterns: ["None", "Weekly", "Fortnightly", "Monthly", "Quarterly"],
      // Add assignees array - will be populated from tasks
      assignees: []
    };

    const STORAGE_KEY = "bellwether_erp_v7_8_state";
    const theEnumsKey = "bellwether_enums_v7_8"; // fixed: declare as const
    const LOGIN_KEY = "bellwether_current_user_id";
    const tz = "Asia/Karachi";

    // Fixed todayISO to use local timezone
    const todayISO = () => {
      const d = new Date();
      // Adjust for timezone offset to get local date
      const offset = d.getTimezoneOffset() * 60000;
      const localDate = new Date(d.getTime() - offset);
      return localDate.toISOString().slice(0, 10);
    };

    const toDate = (iso) => new Date(iso + "T00:00:00");
    const uid = () => Math.random().toString(36).slice(2) + Date.now().toString(36);

    // Convert a Date object to a YYYY-MM-DD string in local time (no timezone shift)
    function toLocalISO(date) {
      const y = date.getFullYear();
      const m = String(date.getMonth() + 1).padStart(2, '0');
      const d = String(date.getDate()).padStart(2, '0');
      return `${y}-${m}-${d}`;
    }

    // Small inline date input that uses native <input type="date">
    function InlineDateCell({ task, field, isOverdue, isEditing, dateDraft, setDateDraft, beginEdit, onCommit, onCancel }) {
      if (!isEditing) {
        const text = task[field] ? fmtDDMMYY(task[field]) : "—";
        return (
          <td style={{ ...tdSlim, color: isOverdue ? "#dc2626" : "inherit", fontWeight: isOverdue ? 600 : 400 }}
            onClick={(e) => { e.stopPropagation(); beginEdit(task, field); }}
            title="Click to edit date">
            {text}
          </td>
        );
      }
      return (
        <td style={{ ...tdSlim }} onClick={(e) => e.stopPropagation()}>
          <input
            type="date"
            value={dateDraft || ""}
            onChange={(e) => setDateDraft(e.target.value)}
            onBlur={() => onCommit(task)}
            onKeyDown={(e) => {
              if (e.key === 'Enter') { onCommit(task); }
              if (e.key === 'Escape') { onCancel(); }
            }}
            style={{ ...inputStyle, padding: "4px 6px", fontSize: 12 }}
            autoFocus
          />
        </td>
      );
    }

    let saveTimer = null;
    function debounce(fn, ms) {
      return (...args) => {
        clearTimeout(saveTimer);
        saveTimer = setTimeout(() => fn(...args), ms);
      };
    }

    const serverSaveStateDebounced = debounce(async (state) => {
      try {
        await fetch(`${window.API_BASE}?op=save`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-ERP-Key': window.API_KEY
          },
          body: JSON.stringify(state)
        });
      } catch (e) {
        console.error('Save failed', e);
      }
    }, 500);

    /* dd-mm-yy <-> ISO helpers */
    function fmtDDMMYY(iso) {
      if (!iso) return "—";
      const d = toDate(iso);
      const dd = String(d.getDate()).padStart(2, "0");
      const mm = String(d.getMonth() + 1).padStart(2, "0");
      const yy = String(d.getFullYear()).slice(-2);
      return `${dd}-${mm}-${yy}`;
    }
    function parseDDMMYY(str) {
      // accepts dd-mm-yy or dd-mm-yyyy; returns ISO yyyy-mm-dd or ""
      // This implementation avoids timezone shifts by constructing the ISO string manually.
      if (!str) return "";
      const m = String(str).trim().match(/^(\d{1,2})[-/](\d{1,2})[-/](\d{2}|\d{4})$/);
      if (!m) return "";
      let dd = parseInt(m[1], 10);
      let mm = parseInt(m[2], 10);
      const yy = m[3];
      const yyyy = (yy.length === 2 ? 2000 + parseInt(yy, 10) : parseInt(yy, 10));
      // Basic range checks
      if (dd < 1 || dd > 31 || mm < 1 || mm > 12) return "";
      const d = new Date(yyyy, mm - 1, dd);
      // Ensure the date is valid (e.g. not 31 February)
      if (d.getFullYear() !== yyyy || d.getMonth() !== mm - 1 || d.getDate() !== dd) return "";
      // Pad numbers to two digits
      const pad = (n) => String(n).padStart(2, '0');
      return `${yyyy}-${pad(mm)}-${pad(dd)}`;
    }

    /* Week helpers (Mon start) */
    function startOfWeekPKT(date = new Date()) {
      const d = new Date(date.toLocaleString("en-US", { timeZone: tz }));
      const day = (d.getDay() + 6) % 7; d.setDate(d.getDate() - day); d.setHours(0, 0, 0, 0); return d;
    }
    function endOfWeekPKT(date = new Date()) {
      const s = startOfWeekPKT(date); const e = new Date(s); e.setDate(e.getDate() + 6); e.setHours(23, 59, 59, 999); return e;
    }

    /* Due Date filter */
    function isTaskInDueFilter(task, filter) {
      if (!task?.due_date) return false;
      const today = new Date(); today.setHours(0, 0, 0, 0);
      const due = toDate(task.due_date);
      const thisStart = startOfWeekPKT(today);
      const thisEnd = endOfWeekPKT(today);
      const nextStart = new Date(thisEnd); nextStart.setDate(thisEnd.getDate() + 1); nextStart.setHours(0, 0, 0, 0);
      const nextEnd = new Date(nextStart); nextEnd.setDate(nextStart.getDate() + 6); nextEnd.setHours(23, 59, 59, 999);
      const monthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0); monthEnd.setHours(23, 59, 59, 999);
      const next30End = new Date(today); next30End.setDate(today.getDate() + 30); next30End.setHours(23, 59, 59, 999);

      switch (filter) {
        case "Today": return due.getTime() === today.getTime() && !["Completed", "Cancelled"].includes(task.status);
        case "Tomorrow": { const t = new Date(today); t.setDate(t.getDate() + 1); return due.getTime() === t.getTime() && !["Completed", "Cancelled"].includes(task.status); }
        case "This Week": return (due >= thisStart && due <= thisEnd) && !["Completed", "Cancelled"].includes(task.status);
        case "Next Week": return (due >= nextStart && due <= nextEnd) && !["Completed", "Cancelled"].includes(task.status);
        case "This Month": return (due >= today && due <= monthEnd) && !["Completed", "Cancelled"].includes(task.status);
        case "Next 30 Days": return (due >= today && due <= next30End) && !["Completed", "Cancelled"].includes(task.status);
        default: return true; // "All"
      }
    }

    function downloadFile(name, content, mime = "text/plain;charset=utf-8") {
      try {
        const blob = new Blob([content], { type: mime });
        const url = (window.URL || window.webkitURL).createObjectURL(blob);
        const a = document.createElement("a");
        a.setAttribute("download", name);
        a.href = url; document.body.appendChild(a); a.click();
        setTimeout(() => { (window.URL || window.webkitURL).revokeObjectURL(url); a.remove(); }, 0);
      } catch {
        const a = document.createElement("a");
        a.setAttribute("download", name);
        a.href = "data:" + mime + "," + encodeURIComponent(content);
        document.body.appendChild(a); a.click(); a.remove();
      }
    }
    function csvEscape(v) { if (v == null) return ""; const s = String(v).replace(/"/g, '""'); return /[",\n]/.test(s) ? `"${s}"` : s; }

    /* ================================ Seed / Store =============================== */
    function seed() {
      // Provide a minimal initial state.  During first render the app will
      // call serverLoadState() to fetch the real data from the backend API.
      // We intentionally avoid seeding clients or tasks here so that demo
      // data like "Raasid Enterprises" or test tasks are not shown by default.
      const clients = [];
      const users = [
        { id: uid(), name: "Arshad Saleem", email: "ceo@thebellcon.com", role: "CEO", department: "Management", active: true },
        { id: uid(), name: "Accounts Lead", email: "accounts@thebellcon.com", role: "Accounts", department: "Accounts", active: true },
        { id: uid(), name: "Audit Head", email: "audit@thebellcon.com", role: "Department Head", department: "Audit", active: true },
        { id: uid(), name: "Tax Head", email: "tax@thebellcon.com", role: "Department Head", department: "Tax", active: true },
        { id: uid(), name: "Corporate Head", email: "corporate@thebellcon.com", role: "Department Head", department: "Corporate", active: true },
        { id: uid(), name: "Admin & HR Head", email: "adminhr@thebellcon.com", role: "Department Head", department: "Admin & HR", active: true },
        { id: uid(), name: "Aizaz", email: "aizaz@thebellcon.com", role: "Partner", department: "Management", active: true },
      ];
      const tasks = [];
      return { clients, users, tasks };
    }
    function loadState() { try { const raw = localStorage.getItem(STORAGE_KEY); return raw ? JSON.parse(raw) : seed(); } catch { return seed(); } }
    function saveState(s) { localStorage.setItem(STORAGE_KEY, JSON.stringify(s)); }

    function loadEnums() {
      try {
        const raw = localStorage.getItem(theEnumsKey);
        const saved = raw ? JSON.parse(raw) : DEFAULT_ENUMS;

        // Extract assignees from existing tasks and merge with saved assignees
        const taskAssignees = [];
        try {
          const state = loadState();
          state.tasks.forEach(t => {
            if (t.assignee && !taskAssignees.includes(t.assignee)) taskAssignees.push(t.assignee);
            if (t.subtasks) {
              t.subtasks.forEach(s => {
                if (s.assignee && !taskAssignees.includes(s.assignee)) taskAssignees.push(s.assignee);
              });
            }
          });
        } catch (e) { }

        // Merge saved assignees with extracted ones
        const mergedAssignees = [...new Set([...(saved.assignees || []), ...taskAssignees])].sort();

        return {
          ...saved,
          assignees: mergedAssignees
        };
      } catch (e) {
        return DEFAULT_ENUMS;
      }
    }
    function saveEnums(e) { localStorage.setItem(theEnumsKey, JSON.stringify(e)); }

    /* ================================ Login Map ================================= */
    const CREDENTIALS = [
      // existing
      { username: "Tax", password: "Tax1001!", matchBy: "name", value: "Tax Head" },
      { username: "Audit", password: "Audit1001!", matchBy: "name", value: "Audit Head" },
      { username: "Accounts", password: "Accounts1001!", matchBy: "name", value: "Accounts Lead" },
      { username: "Corporate", password: "Corporate1001!", matchBy: "name", value: "Corporate Head" },

      // Arshad (two ways to log in)
      { username: "CEO", password: "CEO1001!", matchBy: "name", value: "Arshad Saleem" },
      { username: "Arshad", password: "CEO1001!", matchBy: "name", value: "Arshad Saleem" },

      // Aizaz
      { username: "Aizaz", password: "Aizaz1001!", matchBy: "name", value: "Aizaz" },

      // Admin & HR
      { username: "Admin & HR", password: "AdminHR1001!", matchBy: "name", value: "Admin & HR Head" },

      // (optional) department-level "Management" alias that logs in as Arshad
      { username: "Management", password: "Mgmt1001!", matchBy: "name", value: "Arshad Saleem" },
    ];

    /* ============================== Overall KPIs View =============================== */
    function OverallKPIsView({ tasks }) {
      const overallStats = useMemo(() => {
        // Count all tasks including subtasks
        let totalTasks = 0;
        let completedTasks = 0;
        let closedTasks = 0;
        let inProgressTasks = 0;
        let notStartedTasks = 0;
        let overdueTasks = 0;

        // Revenue variables
        let totalRevenue = 0;
        let collectedRevenue = 0;
        let pendingRevenue = 0;

        const processItem = (item, isSubtask = false) => {
          // Skip cancelled items for all metrics except maybe a specialized count if we had one
          if (item.status === "Cancelled") return;

          totalTasks++;

          // Status counts
          const isComp = isSubtask ? (item.done || item.status === "Completed") : (item.status === "Completed");
          const isClosed = isComp && (item.invoice_status === 'Paid' || item.invoice_status === 'N/A');

          if (isClosed) {
            closedTasks++;
            completedTasks++;
          } else if (isComp) {
            completedTasks++;
          } else if (item.status === "In Progress") {
            inProgressTasks++;
          } else if (!item.status || item.status === "Not Started") {
            notStartedTasks++;
          }

          // Overdue logic
          const now = new Date();
          now.setHours(0, 0, 0, 0);
          const isOverdue = !isComp && item.due_date && (toDate(item.due_date) < now);
          if (isOverdue) overdueTasks++;

          // Revenue logic (Match Invoice Oversight criteria)
          const amount = Number(item.invoice_amount) || 0;
          const paid = Number(item.paid_amount) || 0;

          // Only count revenue for items that are COMPLETED and INVOICE ISSUED
          if (isComp && item.invoice_issued && item.invoice_status !== "N/A") {
            totalRevenue += amount;
            collectedRevenue += paid;

            const balance = amount - paid;
            pendingRevenue += (balance > 0 ? balance : 0);
          }
        };

        tasks.forEach(t => {
          processItem(t);
          if (t.subtasks && t.subtasks.length > 0) {
            t.subtasks.forEach(s => processItem(s, true));
          }
        });

        return {
          totalTasks,
          completedTasks,
          closedTasks,
          inProgressTasks,
          notStartedTasks,
          overdueTasks,
          totalRevenue,
          collectedRevenue,
          pendingRevenue,
          completionRate: totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0,
          collectionRate: totalRevenue > 0 ? Math.round((collectedRevenue / totalRevenue) * 100) : 0,
        };
      }, [tasks]);

      return (
        <div style={{ maxHeight: '60vh', overflow: 'auto' }}>
          {/* Overall KPIs Grid */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))', gap: 12, marginBottom: 20 }}>
            <div style={{ background: 'linear-gradient(135deg, #f1f5f9, #cbd5e1)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#334155' }}>{overallStats.totalTasks}</div>
              <div style={{ fontSize: 12, color: '#475569', fontWeight: 600 }}>Total Tasks</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #fffbeb, #fef3c7)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#92400e' }}>{overallStats.notStartedTasks}</div>
              <div style={{ fontSize: 12, color: '#b45309', fontWeight: 600 }}>Not Started</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #e0e7ff, #c7d2fe)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#3730a3' }}>{overallStats.inProgressTasks}</div>
              <div style={{ fontSize: 12, color: '#4f46e5', fontWeight: 600 }}>In Progress</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #bbf7d0, #86efac)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#166534' }}>{overallStats.completedTasks}</div>
              <div style={{ fontSize: 12, color: '#16a34a', fontWeight: 600 }}>Completed</div>
              <div style={{ fontSize: 11, color: '#475569', marginTop: 4 }}>{overallStats.completionRate}% rate</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #d1fae5, #6ee7b7)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#064e3b' }}>{overallStats.closedTasks}</div>
              <div style={{ fontSize: 12, color: '#047857', fontWeight: 600 }}>Closed</div>
              <div style={{ fontSize: 11, color: '#475569', marginTop: 4 }}>Paid & Done</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #fee2e2, #fca5a5)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#991b1b' }}>{overallStats.overdueTasks}</div>
              <div style={{ fontSize: 12, color: '#dc2626', fontWeight: 600 }}>Overdue</div>
            </div>
          </div>

          {/* Revenue KPIs */}
          <h4 style={{ margin: '20px 0 12px 0', fontSize: 14, color: '#475569' }}>Revenue Overview</h4>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 12 }}>
            <div style={{ background: 'linear-gradient(135deg, #dbeafe, #93c5fd)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#1e40af' }}>PKR {overallStats.totalRevenue.toLocaleString()}</div>
              <div style={{ fontSize: 12, color: '#3b82f6', fontWeight: 600 }}>Total Revenue</div>
              <div style={{ fontSize: 11, color: '#475569', marginTop: 4 }}>Includes subtasks</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #dcfce7, #86efac)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#166534' }}>PKR {overallStats.collectedRevenue.toLocaleString()}</div>
              <div style={{ fontSize: 12, color: '#16a34a', fontWeight: 600 }}>Collected</div>
              <div style={{ fontSize: 11, color: '#475569', marginTop: 4 }}>{overallStats.collectionRate}% collected</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #fee2e2, #fca5a5)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#991b1b' }}>PKR {overallStats.pendingRevenue.toLocaleString()}</div>
              <div style={{ fontSize: 12, color: '#dc2626', fontWeight: 600 }}>Pending</div>
            </div>
          </div>
        </div>
      );
    }


    /* ================================== App ===================================== */
    function App() {

      // Smart invoicing decision for main task vs subtasks
      // Smart invoicing decision for main task vs subtasks
      const openInvoiceSmart = (task) => {
        if (!task) { setShowInvoicePanel(true); return; }

        const subs = Array.isArray(task.subtasks) ? task.subtasks : [];
        const mainInvoiced = task.invoice_status && task.invoice_status !== "Not Issued";
        const invoicedSubs = subs.filter(function (s) { return s && s.invoice_status && s.invoice_status !== "Not Issued"; });

        // No subtasks or main already invoiced -> open panel
        if (subs.length === 0 || mainInvoiced) {
          setShowInvoicePanel(true);
          return;
        }

        // Build message safely with escaped newlines
        var message = "This task has subtasks.\n\n";
        if (invoicedSubs.length > 0) {
          message += "Some subtasks are already invoiced.\n";
          message += "Invoiced subtasks:\n";
          invoicedSubs.forEach(function (s) { message += "- " + (s.title || s.task_description || "Subtask") + "\n"; });
          message += "\n";
        }
        message += "Press OK to invoice the MAIN TASK.\n";
        message += "Press Cancel to review / invoice SUBTASKS instead.";

        var proceedMain = window.confirm(message);
        if (proceedMain) { setShowInvoicePanel(true); return; }
        return;
      };


      // Start with seed immediately (fast paint), then hydrate from server
      const [state, setState] = useState(() => {
        const s = loadState(); // loads from localStorage if present, else seeds
        saveState(s);          // ensure we persist the very first seed (stable IDs)
        return s;
      });
      const [hydrated, setHydrated] = useState(false);
      const serverHydratedRef = useRef(false);

      // For Bulk Import: track per-row new client names when the "Add new client" option is chosen.
      // Keys are row indices. When a row's client field is set to the special value
      // '__input__', we display a text box and store the typed name in this map.
      const [importNewClients, setImportNewClients] = useState({});

      // For renaming clients in the Task Editor.
      const [clientEditMode, setClientEditMode] = useState(false);
      const [editingClientNameInput, setEditingClientNameInput] = useState("");

      // For renaming departments in the Task Editor.
      const [deptEditMode, setDeptEditMode] = useState(false);
      const [editingDeptNameInput, setEditingDeptNameInput] = useState("");

      // For assignee management in task editor
      const [newAssigneeMode, setNewAssigneeMode] = useState(false);
      const [newAssigneeName, setNewAssigneeName] = useState("");
      const [assigneeEditMode, setAssigneeEditMode] = useState(false);
      const [editingAssigneeName, setEditingAssigneeName] = useState("");

      // For delete confirmation
      const [taskToDelete, setTaskToDelete] = useState(null);

      // Client filter search functionality
      useEffect(() => {
        const handleClientSearch = (e) => {
          if (e.target.id && e.target.id.startsWith('client-search-')) {
            const searchTerm = e.target.value.toLowerCase();
            const dropdown = e.target.closest('[style*="position: absolute"]');
            if (dropdown) {
              const options = dropdown.querySelectorAll('label');
              options.forEach(option => {
                const text = option.textContent.toLowerCase();
                if (text.includes(searchTerm)) {
                  option.style.display = 'flex';
                } else {
                  option.style.display = 'none';
                }
              });
            }
          }
        };

        document.addEventListener('input', handleClientSearch);
        return () => document.removeEventListener('input', handleClientSearch);
      }, []);

      useEffect(() => {
        let mounted = true;
        (async () => {
          try {
            const remote = await serverLoadState();
            if (mounted && remote && Array.isArray(remote.tasks)) {
              setState(s => ({
                ...s,
                tasks: Array.isArray(remote.tasks) && remote.tasks.length ? remote.tasks : s.tasks,
                clients: Array.isArray(remote.clients) && remote.clients.length ? remote.clients : s.clients,
                users: Array.isArray(remote.users) && remote.users.length ? remote.users : s.users,
              }));
            }
          } catch (e) {
            console.warn('Could not load server state, staying on seed/local.', e);
          } finally {
            if (mounted) setHydrated(true);
          }
        })();
        return () => { mounted = false; };
      }, []);

      // Save to server whenever state changes (guard against wiping)
      useEffect(() => {
        if (!hydrated) return;
        const nonEmptyLocal = ((state.tasks?.length || 0) + (state.clients?.length || 0)) > 0;
        if (!serverHydratedRef.current && !nonEmptyLocal) return;
        if (!nonEmptyLocal) return;
        serverSaveStateDebounced(state);
      }, [state, hydrated]);
      // Save locally on every change (keeps IDs stable across reloads & helps the bridge script)
      useEffect(() => {
        saveState(state);
      }, [state]);

      // Mutable enums
      const [enums, setEnums] = useState(() => loadEnums());
      useEffect(() => { saveEnums(enums); }, [enums]);

      // Reset department filter when user changes
      useEffect(() => {
        if (!canViewAllDepartments() && currentUser?.department) {
          setFilters(f => ({ ...f, department: currentUser.department }));
        } else {
          setFilters(f => ({ ...f, department: "All" }));
        }
      }, [currentUser]);

      const clientsById = useMemo(() => Object.fromEntries(state.clients.map(c => [c.id, c])), [state.clients]);
      const usersById = useMemo(() => Object.fromEntries(state.users.map(u => [u.id, u])), [state.users]);

      const [filters, setFilters] = useState({
        department: [],
        client: [],
        status: [],
        invoice_status: []
      });
      const [dueFilter, setDueFilter] = useState("All");
      const [q, setQ] = useState("");

      // Toggle between normal task list and recurring task list.  When false, show
      // only tasks without a recurrence pattern; when true, show tasks that recur.
      const [showRecurring, setShowRecurring] = useState(false);

      // Note: listForDisplay will be defined after the `filtered` variable is declared
      // because it depends on `filtered`.  See further down in the code for the
      // definition.

      // Current user is stored after login
      const [currentUserId, setCurrentUserId] = useState(() => localStorage.getItem(LOGIN_KEY) || "");
      // Inline date editing (main task list)
      const [editingDate, setEditingDate] = useState({ id: null, field: null });
      const [dateDraft, setDateDraft] = useState("");

      const beginInlineDateEdit = (task, field) => {
        if (!task) return;
        setEditingDate({ id: task.id, field });
        setDateDraft(task[field] || "");
      };
      const commitInlineDateEdit = (task) => {
        if (!editingDate.id || !editingDate.field) return;
        const iso = dateDraft || "";
        if (iso !== (task[editingDate.field] || "")) {
          upsertTask({ ...task, [editingDate.field]: iso });
        }
        setEditingDate({ id: null, field: null });
      };
      const cancelInlineDateEdit = () => setEditingDate({ id: null, field: null });

      const [showLogin, setShowLogin] = useState(() => !localStorage.getItem(LOGIN_KEY));
      const currentUser = usersById[currentUserId];
      // Note: do not early-return here.  We handle the login screen later in the UI section to keep
      // hook ordering consistent across renders.  If the user is not logged in or the ID is invalid,
      // we fall back to showing the login screen by computing a flag later.

      // Ensure validity of persisted user
      useEffect(() => {
        if (!hydrated) return; // wait until remote load attempt finishes
        if (currentUserId && !usersById[currentUserId]) {
          localStorage.removeItem(LOGIN_KEY);
          setShowLogin(true);
        }
      }, [currentUserId, usersById, hydrated]);

      const [showImport, setShowImport] = useState(false);
      const [showCalendar, setShowCalendar] = useState(false);
      // Toggle for the reporting dashboard
      const [showReport, setShowReport] = useState(false);
      const [reportView, setReportView] = useState('department'); // 'department', 'assignee', 'overall'
      const [reportPeriod, setReportPeriod] = useState('all'); // for assignee performance time period
      const [reportAssigneeFilter, setReportAssigneeFilter] = useState('All'); // for assignee performance view

      const [showInvoicePanel, setShowInvoicePanel] = useState(false);
      const [selectedTasks, setSelectedTasks] = useState(new Set());
      const [showBulkEdit, setShowBulkEdit] = useState(false);
      const [showBulkDelete, setShowBulkDelete] = useState(false); // Added for bulk delete
      const [selectedTaskForReminders, setSelectedTaskForReminders] = useState(null);
      const [selectedSubtaskForReminders, setSelectedSubtaskForReminders] = useState(null);
      const [selectedSubtaskIndex, setSelectedSubtaskIndex] = useState(null);
      const [newReminderNote, setNewReminderNote] = useState("");
      const [newReminderDate, setNewReminderDate] = useState(todayISO());
      const [selectedAssigneeDetails, setSelectedAssigneeDetails] = useState(null);
      const [modalStatusFilter, setModalStatusFilter] = useState('All');
      const [reportShowFinancials, setReportShowFinancials] = useState(false);
      // Expanded bulkDraft to include status, department, and priority
      const [bulkDraft, setBulkDraft] = useState({
        status: '', department: '', priority: '',
        invoice_issued: null, invoice_na: null, invoice_status: ''
      });

      const [invoiceDept, setInvoiceDept] = useState('All');

      const [invoiceClientFilter, setInvoiceClientFilter] = useState([]);
      const [showInvoiceClientFilter, setShowInvoiceClientFilter] = useState(false);

      const [invoiceClient, setInvoiceClient] = useState('All');
      const departmentOptions = useMemo(() => ['All', ...Array.from(new Set((state?.tasks || []).map(t => t.department).filter(Boolean))).sort()], [state.tasks]);

      // Date range for Invoice Oversight: uses ISSUED date
      const [expandedParents, setExpandedParents] = useState({});

      // Expand / collapse all helper (Invoice Oversight header arrow)
      const toggleExpandAll = (tasks) => {
        const parentsWithSubs = tasks.filter(t => Array.isArray(t.subtasks) && t.subtasks.length > 0);
        const allExpanded = parentsWithSubs.every(t => expandedParents[t.id]);

        if (allExpanded) {
          // collapse all
          setExpandedParents({});
        } else {
          // expand all
          const next = {};
          parentsWithSubs.forEach(t => { next[t.id] = true; });
          setExpandedParents(next);
        }
      };


      const [invoiceFrom, setInvoiceFrom] = useState('');
      const [invoiceTo, setInvoiceTo] = useState('');


      const [quickRange, setQuickRange] = useState('all');
      const [invoiceStatusFilter, setInvoiceStatusFilter] = useState('All');
      const [invoiceSearch, setInvoiceSearch] = useState('');

      useEffect(() => {
        const now = new Date();
        const y = now.getFullYear(), m = now.getMonth(), d = now.getDate();
        const today = new Date(y, m, d);
        const toISO = (dt) => new Date(dt.getTime() - dt.getTimezoneOffset() * 60000).toISOString().slice(0, 10);

        if (quickRange === 'all') {
          setInvoiceFrom('');
          setInvoiceTo('');
        } else if (quickRange === 'today') {
          setInvoiceFrom(toISO(today));
          setInvoiceTo(toISO(today));
        } else if (quickRange === 'week') {
          const mon = new Date(today); const k = (mon.getDay() + 6) % 7; mon.setDate(mon.getDate() - k);
          setInvoiceFrom(toISO(mon)); setInvoiceTo(toISO(today));
        } else if (quickRange === 'month') {
          const first = new Date(y, m, 1);
          setInvoiceFrom(toISO(first)); setInvoiceTo(toISO(today));
        } else if (quickRange === 'year') {
          const firstY = new Date(y, 0, 1);
          setInvoiceFrom(toISO(firstY)); setInvoiceTo(toISO(today));
        } else if (quickRange === 'last_week') {
          const mon = new Date(today); const k = (mon.getDay() + 6) % 7; mon.setDate(mon.getDate() - k - 7);
          const sun = new Date(mon); sun.setDate(mon.getDate() + 6);
          setInvoiceFrom(toISO(mon)); setInvoiceTo(toISO(sun));
        } else if (quickRange === 'last_month') {
          const firstPrev = new Date(y, m - 1, 1);
          const lastPrev = new Date(y, m, 0);
          setInvoiceFrom(toISO(firstPrev)); setInvoiceTo(toISO(lastPrev));
        } else if (quickRange === 'last_year') {
          const firstPrevY = new Date(y - 1, 0, 1);
          const lastPrevY = new Date(y - 1, 11, 31);
          setInvoiceFrom(toISO(firstPrevY)); setInvoiceTo(toISO(lastPrevY));
        }
      }, [quickRange]);
      // Return true if a task is inside the selected issued-date range
      const invoiceInRange = (t) => {
        if (!invoiceFrom && !invoiceTo) return true;
        if (!t || !t.invoice_issued || !t.invoice_issued_date) return false;
        const dt = toDate(String(t.invoice_issued_date));
        if (invoiceFrom) { const from = toDate(invoiceFrom); if (dt < from) return false; }
        if (invoiceTo) { const to = toDate(invoiceTo); to.setHours(23, 59, 59, 999); if (dt > to) return false; }
        return true;
      };

      // KPIs (department scoped only)
      const kpisForDept = useMemo(() => {
        const list = (state.tasks || [])
          .filter(t => t.status === "Completed" || ((t.subtasks || []).some(s => s && (s.status === 'Completed' || s.done))))
          .filter(t => (invoiceDept === "All" || t.department === invoiceDept) && (invoiceClient === "All" || t.client_id === invoiceClient));
        const amt = (t) => Number(t.invoice_amount) || 0;
        const parse = (s) => {
          if (!s) return null;
          const p = String(s).split('-').map(x => parseInt(x, 10));
          if (p.length === 3) {
            let [d, m, y] = p; y = y < 100 ? 2000 + y : y; return new Date(y, m - 1, d);
          }
          const d = new Date(s); return isNaN(d) ? null : d;
        };
        const now = new Date();
        const sod = new Date(now.getFullYear(), now.getMonth(), now.getDate());
        const sow = (() => { const d = new Date(sod); const k = (d.getDay() + 6) % 7; d.setDate(d.getDate() - k); return d; })(); // Monday start
        const som = new Date(now.getFullYear(), now.getMonth(), 1);
        const soy = new Date(now.getFullYear(), 0, 1);
        const sumSince = (start) => list.reduce((s, t) => { const dt = parse(t.completion_date); return dt && dt >= start ? s + amt(t) : s; }, 0);
        return [
          ["Today", sumSince(sod)],
          ["This Week", sumSince(sow)],
          ["This Month", sumSince(som)],
          ["This Year", sumSince(soy)],
        ];
      }, [state.tasks, invoiceDept]);
      const [calendarMode, setCalendarMode] = useState("month"); // day | week | month | year
      const [calendarAnchorDate, setCalendarAnchorDate] = useState(new Date());
      const [calendarBy, setCalendarBy] = useState("due"); // due | start

      // Calendar filtering by department.  Only applies when owner/management. Default 'All'
      const [calendarDeptFilter, setCalendarDeptFilter] = useState('All');

      // Calendar filtering by assignee
      const [calendarAssigneeFilter, setCalendarAssigneeFilter] = useState('All');

      // Report filtering by department. Allows management to filter the report by department.
      const [reportDeptFilter, setReportDeptFilter] = useState('All');
      const [reportStatusFilter, setReportStatusFilter] = useState('All');

      const makeEmptyRow = () => ({ client: "", department: "", description: "", start: "", due: "", status: "", invoice: "" });
      const [importRows, setImportRows] = useState(() => Array.from({ length: 6 }, () => makeEmptyRow())); // 6 starter rows

      // Enrich
      const enriched = useMemo(() => {
        const now = new Date();
        return state.tasks.map(t => {
          const thread = Array.isArray(t.comments_thread) ? t.comments_thread : (
            t.comments ? [{ id: uid(), user_id: state.users[0]?.id, text: t.comments, ts: new Date().toISOString(), imported: true }] : []
          );
          const subs = Array.isArray(t.subtasks) ? t.subtasks : [];
          const done = subs.filter(s => s.done).length, total = subs.length;
          return {
            ...t,
            // Ensure the flags exist (for backward compatibility)
            quote_approved: t.quote_approved || false,
            advance_received: t.advance_received || false,
            comments_thread: thread,
            subtasks: subs,
            sub_count: { done, total },
            is_overdue: (!["Completed", "Cancelled"].includes(t.status)) && (t.due_date && toDate(t.due_date) < new Date(now.toDateString()))
          };
        });
      }, [state.tasks, state.users]);

      // PERMISSIONS • who can edit/delete a task and view all departments
      const canEditTask = (task) => {
        // Returns true if the current user is allowed to edit or create the given task.
        // Management, CEO and Admin & HR always have full permissions.  Other users
        // may create new tasks or edit tasks that belong to their own department.  This
        // satisfies the requirement that users can add tasks relevant to their own
        // department but cannot modify tasks outside their scope.
        if (!currentUser) return false;
        const allowedRoles = ["CEO", "Management", "Admin & HR"];
        const allowedUsers = ["Arshad Saleem", "Aizaz"];
        // global permission for certain roles or specific users
        if (allowedRoles.includes(currentUser.role) ||
          allowedRoles.includes(currentUser.department) ||
          allowedUsers.includes(currentUser.name)) {
          return true;
        }
        // If there is no task provided (e.g. when creating a new task), allow
        // creation for the user's own department (handled by disabling the
        // department selector elsewhere).  A new task is indicated by missing id.
        if (!task || !task.id) {
          return true;
        }
        // Otherwise only allow editing if the task's department matches the user's department
        return task.department === currentUser.department;
      };

      // Check if user can view all departments
      const canViewAllDepartments = () => {
        if (!currentUser) return false;

        const allowedRoles = ["CEO", "Management", "Admin & HR"];
        const allowedUsers = ["Arshad Saleem", "Aizaz"];

        return (
          allowedRoles.includes(currentUser.role) ||
          allowedRoles.includes(currentUser.department) ||
          allowedUsers.includes(currentUser.name)
        );
      };

      // Can manage invoices? Only CEO, Arshad, Aizaz and Accounts
      const canManageInvoices = () => {
        if (!currentUser) return false;
        const names = ["Arshad", "Arshad Saleem", "Aizaz"];
        if (currentUser.role === "CEO") return true;
        if (names.includes(currentUser.name)) return true;
        if (currentUser.department === "Accounts" || currentUser.role === "Accounts") return true;
        return false;
      };


      // Filter list area
      const filtered = useMemo(() => {
        const ql = q.trim().toLowerCase();

        // Determine if user can view all departments
        const hasViewAllPermission = canViewAllDepartments();

        // Helper function to check if a value matches filter (supports both single values and arrays)
        const matchesFilter = (value, filter) => {
          if (filter === "All" || filter === "" || !filter) return true;
          if (Array.isArray(filter)) {
            return filter.length === 0 || filter.includes(value);
          }
          return value === filter;
        };

        // Filter tasks based on selected filters and search query, then sort by client name descending.
        const arr = enriched.filter(t => {
          // Department restriction: include tasks OR their subtasks that match department
          const canViewAll = (typeof hasViewAllPermission !== 'undefined' ? hasViewAllPermission
            : (typeof isOwner !== 'undefined' ? isOwner : false));

          // Handle department filter (supports arrays now)
          if (!canViewAll) {
            const myDept = currentUser?.department;
            const belongs = (t.department === myDept) || (Array.isArray(t.subtasks) && t.subtasks.some(s => s.department === myDept));
            if (!belongs) return false;
          } else if (!matchesFilter(t.department, filters.department)) {
            // Check if any subtask matches the department filter
            const subtaskMatches = Array.isArray(t.subtasks) &&
              t.subtasks.some(s => matchesFilter(s.department, filters.department));
            if (!subtaskMatches) return false;
          }

          // Client filter (supports arrays now)
          if (!matchesFilter(t.client_id, filters.client)) {
            // Check if any subtask matches the client filter
            const subtaskMatches = Array.isArray(t.subtasks) &&
              t.subtasks.some(s => matchesFilter(s.client_id, filters.client));
            if (!subtaskMatches) return false;
          }

          // Handle status filters (supports arrays now)
          if (Array.isArray(filters.status)) {
            if (filters.status.length > 0) {
              // Special handling for "Closed" if it's in the array
              if (filters.status.includes("Closed")) {
                // Check if task is completed and invoiced (paid or N/A)
                const isClosed = (t.status === "Completed") &&
                  (t.invoice_status === "Paid" || t.invoice_status === "N/A");
                if (!isClosed) return false;
              } else {
                // Regular status filtering
                let matches = false;
                filters.status.forEach(statusFilter => {
                  if (statusFilter === "Quote Approved") {
                    if (t.quote_approved) matches = true;
                  } else if (statusFilter === "Advance received") {
                    if (t.advance_received) matches = true;
                  } else if (statusFilter === "Overdue") {
                    // For "Overdue", check both the status string and the is_overdue flag
                    if (t.is_overdue || (t.status && t.status.includes("Overdue"))) {
                      matches = true;
                    }
                  } else if (t.status && t.status.includes(statusFilter)) {
                    matches = true;
                  }
                });
                if (!matches) return false;
              }
            }
          } else {
            // Backward compatibility for single status filter
            if (filters.status === "Closed") {
              if (!((t.status === "Completed") && (t.invoice_status === "Paid" || t.invoice_status === "N/A"))) {
                return false;
              }
            } else if (filters.status !== "All") {
              if (filters.status === "Quote Approved") {
                if (!t.quote_approved) return false;
              } else if (filters.status === "Advance received") {
                if (!t.advance_received) return false;
              } else if (filters.status === "Overdue") {
                // For "Overdue", check both the status string and the is_overdue flag
                if (!(t.is_overdue || (t.status && t.status.includes("Overdue")))) {
                  return false;
                }
              } else {
                if (!t.status || !t.status.includes(filters.status)) {
                  return false;
                }
              }
            }
          }

          // Invoice status filter (supports arrays now)
          if (Array.isArray(filters.invoice_status)) {
            if (filters.invoice_status.length > 0) {
              let matches = false;
              filters.invoice_status.forEach(invFilter => {
                if (invFilter === "Issued") {
                  if (t.invoice_issued) matches = true;
                } else if (t.invoice_status === invFilter) {
                  matches = true;
                }
              });
              if (!matches) return false;
            }
          } else {
            // Backward compatibility for single invoice filter
            if (filters.invoice_status !== "All") {
              if (filters.invoice_status === "Issued") {
                if (!t.invoice_issued) return false;
              } else {
                if (t.invoice_status !== filters.invoice_status) return false;
              }
            }
          }

          // Apply due date bucketing if selected (this remains single select)
          if (dueFilter !== "All" && !isTaskInDueFilter(t, dueFilter)) return false;

          // Search bar filter on client name or description
          if (ql) {
            const clientName = (clientsById[t.client_id]?.name || "").toLowerCase();
            const desc = (t.task_description || "").toLowerCase();
            if (!clientName.includes(ql) && !desc.includes(ql)) return false;
          }
          return true;
        });

        // Sort by client name ascending (A→Z)
        arr.sort((a, b) => {
          const nameA = (clientsById[a.client_id]?.name || "").toLowerCase();
          const nameB = (clientsById[b.client_id]?.name || "").toLowerCase();
          return nameA.localeCompare(nameB);
        });
        return arr;
      }, [enriched, filters, q, clientsById, dueFilter, currentUser]);

      // Determine which tasks should be visible in the table based on the
      // showRecurring flag.  Recurring tasks are those whose recurrence pattern is not
      // "None".  If a task has no recurrence field it is considered non‑recurring.
      // This hook is defined here (after `filtered`) to ensure `filtered` has been
      // initialized.  Defining it above would capture an undefined `filtered` in the
      // closure and cause runtime errors when `.filter` is called.
      const listForDisplay = useMemo(() => {
        return filtered.filter(t => showRecurring ? (t.recurrence && t.recurrence !== "None") : (!t.recurrence || t.recurrence === "None"));
      }, [filtered, showRecurring]);

      // Export filtered • now with dd-mm-yy dates
      const exportFilteredCSV = () => {
        try {
          const header = ["Client", "Department", "Task Description", "Start Date", "Due Date", "Completed", "Status", "Invoice Status", "Comments Count", "Subtasks Done", "Subtasks Total"];
          const rowsData = filtered.map(t => [
            clientsById[t.client_id]?.name || "",
            t.department,
            t.task_description,
            fmtDDMMYY(t.start_date),
            fmtDDMMYY(t.due_date),
            t.completion_date ? fmtDDMMYY(t.completion_date) : "",
            t.status,
            t.invoice_status,
            (t.comments_thread || []).length,
            t.sub_count?.done || 0,
            t.sub_count?.total || 0
          ]);
          const csvContent = [header, ...rowsData].map(r => r.map(csvEscape).join(",")).join("\n");
          downloadFile(`bellwether_tasks_${todayISO()}.csv`, "\uFEFF" + csvContent, "text/csv;charset=utf-8");
        } catch (e) { console.error(e); alert("Export failed. Please try again."); }
      };

      // CRUD
      const upsertTask = (task) => setState(s => {
        const i = s.tasks.findIndex(x => x.id === task.id);
        const row = { ...task };
        return i >= 0 ? { ...s, tasks: Object.assign([...s.tasks], { [i]: row }) } : { ...s, tasks: [row, ...s.tasks] };
      });

      // Delete task with confirmation
      const deleteTask = (taskId) => {
        if (!canDeleteTask()) return;
        setTaskToDelete(taskId);
      };

      const confirmDelete = () => {
        if (!canDeleteTask()) { setTaskToDelete(null); return; }
        if (taskToDelete) {
          setState(s => ({ ...s, tasks: s.tasks.filter(t => t.id !== taskToDelete) }));
          setTaskToDelete(null);
        }
      };

      const cancelDelete = () => {
        setTaskToDelete(null);
      };
      // Create a duplicate of an existing task
      const duplicateTask = (orig) => {
        if (!orig) return;
        const copy = {
          ...orig,
          id: uid(),
          completion_date: null,
          comments_thread: Array.isArray(orig.comments_thread) ? [...orig.comments_thread] : [],
          subtasks: Array.isArray(orig.subtasks) ? orig.subtasks.map(s => ({ ...s, id: uid(), done: false })) : []
        };
        setState(s => ({ ...s, tasks: [copy, ...s.tasks] }));
      };


      // Comments operations
      const addComment = (taskId, user_id, text) => {
        const ts = new Date().toISOString();
        setState(s => ({ ...s, tasks: s.tasks.map(t => t.id === taskId ? { ...t, comments_thread: [...(t.comments_thread || []), { id: uid(), user_id, text, ts }] } : t) }));
      };

      // Editor modal
      const [showEditor, setShowEditor] = useState(false);
      const [editing, setEditing] = useState(null);
      const [newClientName, setNewClientName] = useState("");
      const [newDeptName, setNewDeptName] = useState("");
      const [newComment, setNewComment] = useState("");

      // Search term for filtering the client dropdown in the task editor.  When
      // the user types into the search box, the client list will be filtered
      // accordingly.  Reset this when opening a new or editing a task.
      const [clientSearchTerm, setClientSearchTerm] = useState('');


      const openNew = () => {
        // Default to the current user's department if available; otherwise fall back to the
        // first department in the list.  This ensures that non‑privileged users create
        // tasks within their own department.
        const defaultDept = currentUser?.department || enums.departments[0];
        const defaultUser = state.users.find(u => u.department === defaultDept)?.id || state.users[0]?.id || "";
        const draft = {
          id: uid(),
          client_id: "", // Reset client dropdown for new tasks
          department: defaultDept,
          task_description: "",
          assignee: "", // NEW: Add assignee field
          job_incharge_user_id: defaultUser,
          start_date: todayISO(),
          due_date: todayISO(),
          completion_date: null,
          // Use separate flags instead of combined status
          status: "Not Started",
          quote_approved: false,
          advance_received: false,
          invoice_status: DEFAULT_ENUMS.invoiceStatus[0],
          comments: "",
          comments_thread: [],
          priority: DEFAULT_ENUMS.priority[2] || "Medium",
          subtasks: [],
          recurrence: "None" // Default recurrence pattern
        };
        setEditing(draft);
        setShowEditor(true);
        // Reset client search term when starting a new task
        setClientSearchTerm('');
      };
      // Only CEO, Arshad, and Aizaz can delete tasks
      const canDeleteTask = () => {
        if (!currentUser) return false;
        if (currentUser.role === 'CEO') return true;
        const allowedUsers = ['Arshad', 'Arshad Saleem', 'Aizaz'];
        return allowedUsers.includes(currentUser.name);
      };

      // When editing an existing task, clear the client search so full list shows
      const openEdit = (task) => {
        setClientSearchTerm('');
        setEditing({ ...task });
        setShowEditor(true);
      };

      const saveEdit = () => {
        const row = { ...editing };
        if (row.status === "Completed" && !row.completion_date) row.completion_date = todayISO();

        // Change log: record modifications on any tracked field.  This includes
        // dates, client, department, description and other metadata.  Use human‑
        // friendly labels and for booleans convert to Yes/No.  Changes are
        // appended to the comments_thread on the task.
        const prev = state.tasks.find(x => x.id === row.id);
        if (prev) {
          const changes = [];
          const who = usersById[currentUserId]?.name || "Unknown";
          const now = new Date().toISOString();
          // Map of keys to labels for change logging
          const keyLabels = {
            client_id: 'Client',
            department: 'Department',
            task_description: 'Description',
            job_incharge_user_id: 'Job incharge',
            start_date: 'Start date',
            due_date: 'Due date',
            completion_date: 'Completion date',
            status: 'Status',
            quote_approved: 'Quote Approved',
            advance_received: 'Advance Received',
            invoice_status: 'Invoice status',
            priority: 'Priority',
            recurrence: 'Recurrence'
          };
          Object.keys(keyLabels).forEach(key => {
            const oldVal = prev[key];
            const newVal = row[key];
            if ((oldVal || '') !== (newVal || '')) {
              let oldDisplay;
              let newDisplay;
              // Special formatting for dates
              if (key.endsWith('_date')) {
                oldDisplay = oldVal ? fmtDDMMYY(oldVal) : '—';
                newDisplay = newVal ? fmtDDMMYY(newVal) : '—';
              } else if (typeof oldVal === 'boolean' || typeof newVal === 'boolean') {
                oldDisplay = oldVal ? 'Yes' : 'No';
                newDisplay = newVal ? 'Yes' : 'No';
              } else if (key === 'client_id') {
                oldDisplay = oldVal ? (clientsById[oldVal]?.name || '—') : '—';
                newDisplay = newVal ? (clientsById[newVal]?.name || '—') : '—';
              } else if (key === 'job_incharge_user_id') {
                oldDisplay = oldVal ? (usersById[oldVal]?.name || '—') : '—';
                newDisplay = newVal ? (usersById[newVal]?.name || '—') : '—';
              } else {
                oldDisplay = (oldVal ?? '').toString();
                newDisplay = (newVal ?? '').toString();
              }
              changes.push({
                id: uid(),
                user_id: currentUserId,
                ts: now,
                text: `${keyLabels[key]} changed by ${who}: ${oldDisplay} → ${newDisplay}`,
                system: true
              });
            }
          });
          if (changes.length) {
            row.comments_thread = [...(prev.comments_thread || []), ...changes];
          }
        }

        upsertTask(row);
        setShowEditor(false);

        // Handle recurring tasks
        if (row.status === "Completed" && row.recurrence !== "None") {
          createNextRecurringTask(row);
        }
      };

      // Create next recurring task
      const createNextRecurringTask = (completedTask) => {
        const newDueDate = calculateNextDueDate(completedTask.due_date, completedTask.recurrence);
        // Fixed: Calculate nextStartDate before using it
        const nextStartDate = calculateNextStartDate(completedTask.start_date, completedTask.recurrence);

        // Start the next recurring task at the previous due date.  This aligns with the
        // requirement that automatically generated tasks should begin on the recurrence
        // date rather than on the day they are completed or created.
        const newTask = {
          ...completedTask,
          id: uid(),
          // When carrying over recurring tasks attach a recurrence_parent_id so that
          // automatic generation logic can detect duplicates.  Default to the
          // completedTask's own parent or id.
          recurrence_parent_id: completedTask.recurrence_parent_id || completedTask.id,
          start_date: nextStartDate,
          due_date: newDueDate,
          status: "Not Started",
          completion_date: null,
          invoice_status: "Not Issued",
          comments_thread: [],
          // reset subtask completion flags
          subtasks: completedTask.subtasks.map(s => ({ ...s, done: false, start_date: nextStartDate, due_date: newDueDate }))
        };
        setState(s => ({ ...s, tasks: [newTask, ...s.tasks] }));
      };

      // Calculate next due date based on recurrence pattern
      const calculateNextDueDate = (currentDueDate, recurrence) => {
        const date = new Date(currentDueDate);

        switch (recurrence) {
          case "Monthly":
            date.setMonth(date.getMonth() + 1);
            break;
          case "Quarterly":
            date.setMonth(date.getMonth() + 3);
            break;
          case "Weekly":
            date.setDate(date.getDate() + 7);
            break;
          case "Fortnightly":
            date.setDate(date.getDate() + 14);
            break;
          default:
            return currentDueDate;
        }

        return toLocalISO(date);
      };

      // Dept delete guard (used in tasks or subtasks)
      const deptUsed = (name) => state.tasks.some(t => t.department === name || (t.subtasks || []).some(s => s.department === name));
      const deleteDepartment = (name) => {
        if (deptUsed(name)) { alert(`Cannot delete "${name}" because it is used by tasks or subtasks.`); return; }
        const nextList = enums.departments.filter(x => x !== name);               // fixed: compute next list
        setEnums(e => ({ ...e, departments: nextList }));
        if (editing?.department === name) {                                   // fixed: safe fallback from next list
          setEditing(v => ({ ...v, department: nextList[0] || "" }));
        }
      };
      const addNewDepartment = () => {
        const name = newDeptName.trim(); if (!name) { alert('Enter department name'); return; }
        if (enums.departments.includes(name)) { alert("Department already exists"); return; }
        setEnums(e => ({ ...e, departments: [...e.departments, name] }));
        setEditing(v => ({ ...v, department: name }));
        setNewDeptName("");
      };

      // KPIs
      const counts = useMemo(() => {
        /*
          Compute KPI counts based on the currently filtered task list rather than all tasks.  This
          ensures the dashboard tiles remain dynamic and reflect the set of tasks the user is
          allowed to see given their department, search query and other filters.  For example,
          when a Tax user signs in, the "All" tile will now show the total number of Tax tasks
          rather than the sum of every department's tasks.  Additional KPIs (quote approved,
          advance received, etc.) are derived from boolean flags on tasks rather than exact
          status strings, so tasks with composite statuses like "Quote Approved & In Progress"
          still count as quote approved.
        */
        const list = filtered;
        const total = list.length;
        const now = new Date();
        const sw = startOfWeekPKT(now), ew = endOfWeekPKT(now);
        const dueWeek = list.filter(t => {
          const d = t.due_date ? toDate(t.due_date) : null;
          return d && d >= sw && d <= ew && !["Completed", "Cancelled"].includes(t.status);
        }).length;
        const quoteApproved = list.filter(t => t.quote_approved).length;
        const advanceReceived = list.filter(t => t.advance_received).length;
        const inProgress = list.filter(t => t.status && t.status.includes("In Progress")).length;
        const completed = list.filter(t => t.status === "Completed").length;
        const overdue = list.filter(t => t.is_overdue || t.status === "Overdue").length;
        const paid = list.filter(t => t.invoice_status === "Paid").length;
        const closed = list.filter(t => t.status === "Completed" && (t.invoice_status === "Paid" || t.invoice_status === "N/A")).length;
        return { total, dueWeek, quoteApproved, advanceReceived, inProgress, completed, overdue, paid, closed };
      }, [filtered]);

      /*
        Automatically generate recurring tasks on or before their due date.  Prior versions
        only created the next instance when the previous one was marked completed.  This
        revised logic calls runCheckRecurring() whenever the task list changes or the app
        loads (after hydration).  The helper scans all tasks with a recurrence pattern and
        creates follow‑up tasks until the next due date is in the future.  A
        recurrence_parent_id flag is used to detect duplicates.
      */

      const runCheckRecurring = useCallback(() => {
        const today = todayISO();
        const pending = [];
        state.tasks.forEach(t => {
          if (!t.recurrence || t.recurrence === "None" || !t.due_date) return;
          let parentId = t.recurrence_parent_id || t.id;
          let dueISO = t.due_date;
          let startISO = t.start_date || t.due_date;
          // iterate through recurrences until due date is after today
          while (dueISO && dueISO <= today) {
            const nextDue = calculateNextDueDate(dueISO, t.recurrence);
            const nextStart = calculateNextStartDate(startISO, t.recurrence);
            if (!nextDue || nextDue === dueISO) break;
            const exists = state.tasks.some(x => (x.recurrence_parent_id || x.id) === parentId && x.due_date === nextDue);
            if (!exists) {
              pending.push({ base: t, startDate: nextStart, dueDate: nextDue, parentId });
            }
            dueISO = nextDue;
            startISO = nextStart;
          }
        });
        if (pending.length) {
          setState(s => {
            let newTasks = [...s.tasks];
            pending.forEach(({ base, startDate, dueDate, parentId }) => {
              newTasks.unshift({
                ...base,
                id: uid(),
                recurrence_parent_id: parentId,
                start_date: startDate,
                due_date: dueDate,
                status: "Not Started",
                completion_date: null,
                invoice_status: "Not Issued",
                comments_thread: [],
                subtasks: base.subtasks.map(s => ({ ...s, done: false, start_date: startDate, due_date: dueDate }))
              });
            });
            return { ...s, tasks: newTasks };
          });
        }
      }, [state.tasks]);

      // Run recurring check after hydration and whenever tasks change
      useEffect(() => {
        if (hydrated) runCheckRecurring();
      }, [hydrated, runCheckRecurring]);

      // Sticky shrink
      const [shrink, setShrink] = useState(false);
      useEffect(() => {
        const onScroll = () => setShrink(window.scrollY > 16);
        onScroll();
        window.addEventListener('scroll', onScroll, { passive: true });
        return () => window.removeEventListener('scroll', onScroll);
      }, []);

      // Responsive layout: detect small screens and toggle filters/tiles visibility
      const [isSmall, setIsSmall] = useState(false);
      // On small screens the filters/tiles menu is hidden by default; on large screens it's visible
      const [showFilters, setShowFilters] = useState(false);
      useEffect(() => {
        const update = () => {
          const small = window.innerWidth < 640;
          setIsSmall(small);
          // When switching to a larger screen, always show filters and tiles
          if (!small) setShowFilters(true);
        };
        update();
        window.addEventListener('resize', update);
        return () => window.removeEventListener('resize', update);
      }, []);

      // ESC key handler for modals - FIXED VERSION
      useEffect(() => {
        const handleEsc = (event) => {
          const key = event.key || event.keyCode;
          if (key === 'Escape' || key === 27) {
            event.preventDefault();

            console.log("ESC pressed. Current modals open:");
            console.log("selectedAssigneeDetails:", !!selectedAssigneeDetails);
            console.log("selectedTaskForReminders:", !!selectedTaskForReminders);
            console.log("showEditor:", showEditor);
            console.log("showReport:", showReport);
            console.log("showCalendar:", showCalendar);
            console.log("showImport:", showImport);
            console.log("showInvoicePanel:", showInvoicePanel);

            // Check modals in order of visual stacking (top-most first)
            // IMPORTANT: Modals INSIDE other modals should be checked FIRST

            // 1. Reminders modal (can appear on top of anything)
            if (selectedTaskForReminders) {
              console.log("Closing reminders modal");
              setSelectedTaskForReminders(null);
              setSelectedSubtaskForReminders(null);
              setSelectedSubtaskIndex(null);
              return;
            }

            // 2. Task editor (big modal) - Check this BEFORE assignee details 
            // because editor can be opened FROM the details view.
            if (showEditor) {
              console.log("Closing task editor");
              setShowEditor(false);
              return;
            }

            // 3. Assignee details modal (INSIDE Reports modal)
            if (selectedAssigneeDetails) {
              console.log("Closing assignee details modal");
              setSelectedAssigneeDetails(null);
              setModalStatusFilter('All');
              return;
            }

            // 4. Reports modal (contains assignee details)
            if (showReport) {
              console.log("Closing reports modal");
              setShowReport(false);
              return;
            }

            // 5. Calendar modal with mode handling
            if (showCalendar) {
              console.log("Handling calendar ESC");
              // Step back through calendar views
              if (calendarMode === "day") {
                setCalendarMode("week");
              } else if (calendarMode === "week") {
                setCalendarMode("month");
              } else if (calendarMode === "month") {
                setCalendarMode("year");
              } else if (calendarMode === "year") {
                setShowCalendar(false);
              }
              return;
            }

            // 6. Import modal
            if (showImport) {
              console.log("Closing import modal");
              setShowImport(false);
              return;
            }

            // 7. Invoice panel
            if (showInvoicePanel) {
              console.log("Closing invoice panel");
              setShowInvoicePanel(false);
              return;
            }

            // 8. Bulk edit modal
            if (showBulkEdit) {
              console.log("Closing bulk edit");
              setShowBulkEdit(false);
              return;
            }

            // 9. Bulk delete modal
            if (showBulkDelete) {
              console.log("Closing bulk delete");
              setShowBulkDelete(false);
              return;
            }

            // 10. Single delete modal
            if (taskToDelete) {
              console.log("Closing single delete");
              setTaskToDelete(null);
              return;
            }
          }
        };

        window.addEventListener('keydown', handleEsc);
        return () => {
          window.removeEventListener('keydown', handleEsc);
        };
      }, [
        showEditor,
        showReport,
        showCalendar,
        calendarMode,
        showImport,
        showInvoicePanel,
        showBulkEdit,
        showBulkDelete,
        taskToDelete,
        selectedTaskForReminders,
        selectedAssigneeDetails,
        modalStatusFilter
      ]);

      /* --------------------------------- UI ----------------------------------- */
      // Calendar data visibility: owner sees all, others only their department.  We compute
      // this before the login check so that hook order remains consistent between
      // renders.  Even when no user is logged in, `currentUser` will be undefined and
      // the memoized computation will fall back to an empty list.
      const isOwner = currentUser?.role === "CEO" || currentUser?.department === "Management" || currentUser?.name === "Arshad Saleem";
      const calendarTasks = useMemo(() => {
        if (isOwner) return enriched;
        const dept = currentUser?.department || "";
        return enriched.filter(t => t.department === dept || (t.subtasks || []).some(s => s.department === dept));
      }, [enriched, currentUser, isOwner]);

      // Apply department filter for the calendar when owner.  If not owner, just return calendarTasks.
      const filteredCalendarTasks = useMemo(() => {
        if (!isOwner) return calendarTasks;

        let filtered = calendarTasks;

        // Apply department filter
        if (calendarDeptFilter !== 'All') {
          filtered = filtered.filter(t => t.department === calendarDeptFilter || (t.subtasks || []).some(s => s.department === calendarDeptFilter));
        }

        // Apply assignee filter
        if (calendarAssigneeFilter !== 'All') {
          filtered = filtered.filter(t =>
            t.assignee === calendarAssigneeFilter ||
            (t.subtasks || []).some(s => s.assignee === calendarAssigneeFilter)
          );
        }

        return filtered;
      }, [calendarTasks, calendarDeptFilter, calendarAssigneeFilter, isOwner]);

      // helper for calendar stepping
      const stepByMode = (mode) => (mode === "day" ? 1 : mode === "week" ? 7 : mode === "month" ? 30 : 365);

      // Determine whether we need to show the login screen.  We check both the explicit
      // `showLogin` flag and whether a valid current user is available.  If not, we
      // render the LoginScreen component.  This conditional is placed here, after all
      // hooks have been called, to avoid violating React's rules of hooks.
      const hasServerSession = !!window.__HAS_SERVER_SESSION;
      const shouldShowLogin = (!hasServerSession) && (showLogin || !currentUserId || !currentUser);
      if (shouldShowLogin) {
        return (
          <LoginScreen
            users={state.users}
            onLogin={(userId) => {
              // Persist the login ID
              localStorage.setItem(LOGIN_KEY, userId);
              setCurrentUserId(userId);
              // Delay hiding the login until the next animation frame to prevent a brief
              // white flash (avoids rendering issues during state transitions)
              requestAnimationFrame(() => setShowLogin(false));
            }}
          />
        );
      }

      const tableWrapperRef = useRef(null);
      const ghostHeaderRef = useRef(null);
      const [showGhost, setShowGhost] = useState(false);
      const [menuHidden, setMenuHidden] = useState(false);
      const [isHoveringTop, setIsHoveringTop] = useState(false);

      const stickyShellRef = useRef(null);
      useEffect(() => {
        if (!stickyShellRef.current) return;
        const observer = new ResizeObserver(() => {
          if (stickyShellRef.current) {
            const height = stickyShellRef.current.offsetHeight;
            document.documentElement.style.setProperty('--sticky-table-header-top', `${height}px`);
          }
        });
        observer.observe(stickyShellRef.current);

        const handleScroll = () => {
          if (!tableWrapperRef.current || !stickyShellRef.current) return;
          const scrollY = window.scrollY;
          const tableRect = tableWrapperRef.current.getBoundingClientRect();
          const shellHeight = stickyShellRef.current.offsetHeight;

          // Auto-hide menu logic
          if (scrollY > 200) {
            setMenuHidden(true);
          } else if (scrollY < 50) {
            setMenuHidden(false);
          }

          // Show ghost header when main table header is scrolled past the shell
          setShowGhost(tableRect.top < shellHeight && tableRect.bottom > shellHeight + 80);

          // Sync horizontal scroll
          if (ghostHeaderRef.current) {
            ghostHeaderRef.current.scrollLeft = tableWrapperRef.current.scrollLeft;
          }
        };

        window.addEventListener('scroll', handleScroll, { passive: true });
        return () => {
          observer.disconnect();
          window.removeEventListener('scroll', handleScroll);
        }
      }, []);

      const onTableScroll = useCallback((e) => {
        if (ghostHeaderRef.current) {
          ghostHeaderRef.current.scrollLeft = e.target.scrollLeft;
        }
      }, []);

      return (
        <div className="min-h-screen" style={{ padding: "0 10px 22px 10px" }} onMouseMove={(e) => {
          // Detect hover at top 60px to show menu
          const nearTop = e.clientY < 60;
          if (nearTop !== isHoveringTop) setIsHoveringTop(nearTop);
        }}>
          {/* Hover detector for hidden menu */}
          <div className="hover-trigger-zone" onMouseEnter={() => setIsHoveringTop(true)} />

          {/* New Reveal Indicator Icon/Tab */}
          <div
            className={`reveal-indicator ${(menuHidden && !isHoveringTop) ? 'visible' : ''}`}
            title="Hover here to show menu & filters"
          >
            <span style={{ marginRight: 6 }}>☰</span>
            <span style={{ fontSize: 10, fontWeight: 700 }}>SHOW FILTERS</span>
          </div>

          {/* Sticky header + tiles + filters */}
          <div ref={stickyShellRef} className={`sticky-shell ${shrink ? 'shrink' : ''}`}>
            <div className="sticky-inner">
              <div className={`menu-collapsible ${(menuHidden && !isHoveringTop) ? 'hidden' : ''}`}>
                {/* Header - Updated for better space utilization */}
                <header style={{ ...cardStyle, padding: (shrink ? "6px 10px" : "10px 12px") }}>
                  <div className="header-compact">
                    <div className="title-section">
                      <h1 style={{ margin: 0 }}>
                        <button type="button" title="Go to Home"
                          onClick={() => {
                            try {
                              // Close any open panels
                              setShowEditor(false);
                              setShowReport(false);
                              setShowCalendar(false);
                              setShowImport(false);
                              setShowInvoicePanel(false);
                              // Reset main task list filters & search
                              setQ("");
                              setFilters({ department: "All", client: "All", status: "All", invoice_status: "All" });
                              setDueFilter("All");
                              setShowRecurring(false);
                              // Reset any invoice oversight filters as well
                              try { setInvoiceDept && setInvoiceDept("All"); } catch (e) { }
                              try { setInvoiceFrom && setInvoiceFrom(""); } catch (e) { }
                              try { setInvoiceTo && setInvoiceTo(""); } catch (e) { }
                              try { setQuickRange && setQuickRange("none"); } catch (e) { }
                              try { setInvoiceStatusFilter && setInvoiceStatusFilter("All"); } catch (e) { }
                              // Scroll to top for the full list view
                              window.scrollTo({ top: 0, behavior: "smooth" });
                            } catch (e) { }
                          }}
                          style={{
                            border: 'none', cursor: 'pointer', fontWeight: 800, fontSize: (shrink ? 16 : 18), padding: '6px 12px', borderRadius: 999,
                            background: 'linear-gradient(90deg, #0ea5e9, #a855f7, #f43f5e)', color: '#fff', boxShadow: '0 2px 4px rgba(0,0,0,0.12)'
                          }}>
                          Bellwether Consulting ERP
                        </button>
                      </h1>
                      <p style={{ margin: 0, color: '#64748b', fontSize: 11, display: 'none' }}>Timezone: Asia/Karachi · Dates shown as dd-mm-yy</p>
                    </div>
                    <div className="user-section">
                      <span style={{ fontSize: 12, color: '#475569' }}>
                        Logged in: <b>{currentUser?.name || 'User'}</b>
                      </span>
                      <button type="button" onClick={() => setShowCalendar(true)} style={btnSmall}>
                        📅 Calendar
                      </button>
                      <button type="button" onClick={openNew} style={btnPrimarySmall}>
                        New Task
                      </button>
                      <button type="button" onClick={() => setShowImport(true)} style={btnSmall}>
                        Bulk Import
                      </button>
                      <button type="button" onClick={exportFilteredCSV} style={btnSmall}>
                        ⬇️ Export
                      </button>

                      {/* ONLY SHOW BULK ACTIONS WHEN ITEMS ARE SELECTED */}
                      {selectedTasks.size > 0 && (
                        <>
                          <span style={{ fontSize: 12, fontWeight: 700, color: '#3b82f6', background: '#eff6ff', padding: '4px 8px', borderRadius: 6 }}>
                            {selectedTasks.size} Selected
                          </span>

                          <button type="button" onClick={() => setShowBulkEdit(true)} style={btnPrimarySmall}>
                            ✎ Bulk Edit
                          </button>

                          {/* Only allow Bulk Delete for authorized users */}
                          {canDeleteTask() && (
                            <button type="button" onClick={() => setShowBulkDelete(true)} style={btnDangerSmall}>
                              🗑️ Bulk Delete
                            </button>
                          )}
                        </>
                      )}

                      <button type="button" onClick={() => setShowReport(true)} style={btnSmall}>
                        📊 Reports
                      </button>

                      {canManageInvoices() && (
                        <button type="button" onClick={() => setShowInvoicePanel(true)} style={btnSmall}>
                          🧾 Invoices
                        </button>
                      )}

                      <button
                        type="button"
                        onClick={() => {
                          try { localStorage.removeItem(LOGIN_KEY); } catch (e) { }
                          window.location.href = '/erp/logout.php';
                        }}
                        style={btnSmall}
                      >
                        Log out
                      </button>
                      {/* On small screens show a menu button to toggle filters and tiles */}
                      {isSmall && (
                        <button type="button" onClick={() => setShowFilters((s) => !s)} style={btnSmall}>
                          ☰ Filters
                        </button>
                      )}
                    </div>
                  </div>
                </header>


                {/* Filters (row or column based on screen size) */}
                {(!isSmall || showFilters) && (
                  <div
                    style={{
                      display: 'grid',
                      gridTemplateColumns: isSmall ? '1fr' : '1.5fr 1fr 1fr 1fr 1fr 1fr 1fr',
                      gap: 6,
                      alignItems: 'end',
                      marginTop: 8,
                    }}
                  >
                    <div>
                      <label style={labelStyleSmall}>{isSmall ? '🔍' : 'Search (Client / Description)'}</label>
                      <div style={{ position: 'relative' }}>
                        <input id="taskSearchInput" style={{ ...controlHeight, height: 28, paddingRight: 26 }} placeholder="Type to filter…" value={q} onChange={(e) => setQ(e.target.value)} />
                        {!!q && (
                          <button type="button" aria-label="Clear search" onClick={() => { setQ(''); const el = document.getElementById('taskSearchInput'); if (el) el.focus(); }}
                            style={{ position: 'absolute', right: 6, top: '50%', transform: 'translateY(-50%)', border: 'none', background: 'transparent', cursor: 'pointer', fontSize: 14, lineHeight: 1 }}>✖</button>
                        )}
                      </div>
                    </div>
                    <ExcelFilter
                      small
                      label="Department"
                      value={filters.department}
                      onChange={(v) => setFilters((f) => ({ ...f, department: v }))}
                      options={
                        canViewAllDepartments()
                          ? enums.departments
                          : [currentUser?.department || '']
                      }
                      disabled={!canViewAllDepartments()}
                    />
                    <ExcelFilter small label="Client" value={filters.client} onChange={(v) => setFilters((f) => ({ ...f, client: v }))} options={state.clients.slice().sort((a, b) => a.name.localeCompare(b.name)).map((c) => ({ label: c.name, value: c.id }))} />
                    <ExcelFilter small label="Status" value={filters.status} onChange={(v) => setFilters((f) => ({ ...f, status: v }))} options={[
                      ...DEFAULT_ENUMS.taskStatus,
                      'Closed',
                      'Quote Approved',
                      'Advance received'
                    ]} />
                    <Select small label="Due Date" value={dueFilter} onChange={setDueFilter} options={[
                      'All',
                      'Overdue',
                      'Today',
                      'Tomorrow',
                      'This Week',
                      'Next Week',
                      'This Month',
                      'Next 30 Days',
                    ]} />

                    <ExcelFilter small label="Invoice" value={filters.invoice_status || 'All'} onChange={(v) => setFilters((f) => ({ ...f, invoice_status: v }))} options={[
                      'Issued',
                      'Unpaid',
                      'Paid',
                      'Partially Paid',
                      'N/A',
                    ]} /></div>
                )}
              </div>

              {/* GHOST HEADER - Renders when table is scrolled up */}
              <div ref={ghostHeaderRef} className="ghost-header-container" style={{ display: showGhost ? 'block' : 'none', padding: '0 10px', marginTop: 4 }}>
                <table style={{ background: '#fff' }}>
                  <thead>
                    <tr style={{ color: "#64748b", textAlign: "left" }}>
                      <th style={{ ...thSlim, width: 40 }}><input type={'checkbox'} aria-label="Select all" checked={listForDisplay.length > 0 && listForDisplay.every(t => selectedTasks.has(t.id))} onChange={(e) => { e.stopPropagation(); if (e.target.checked) { setSelectedTasks(new Set(listForDisplay.map(t => t.id))); } else { setSelectedTasks(new Set()); } }} /></th>
                      <th style={{ ...thSlim, width: 34 }}>#</th>
                      <th style={thSlim}>Client</th>
                      <th style={thSlim}>Dept</th>
                      <th style={thSlim}>Assignee</th>
                      <th style={{ textAlign: 'left', fontSize: 11, fontWeight: 600, color: '#64748b', textTransform: 'uppercase', padding: '6px 4px' }}>
                        <button
                          onClick={() => toggleExpandAll(listForDisplay)}
                          style={{
                            border: 'none',
                            background: 'transparent',
                            cursor: 'pointer',
                            marginRight: 6,
                            fontSize: 12,
                            verticalAlign: 'middle'
                          }}
                          title="Expand / collapse all subtasks"
                        >
                          {(() => {
                            const parents = listForDisplay.filter(t => Array.isArray(t.subtasks) && t.subtasks.length > 0);
                            const allExpanded = parents.length > 0 && parents.every(t => expandedParents[t.id]);
                            return allExpanded ? '▼' : '▶';
                          })()}
                        </button>
                        Description
                      </th>
                      <th style={thSlim}>Due</th>
                      <th style={thSlim}>Status</th>
                      <th style={thSlim}>Invoice</th>
                      <th style={{ ...thSlim, textAlign: "right", paddingRight: 6, width: 80 }}>Actions</th>
                    </tr>
                  </thead>
                </table>
              </div>
            </div>
          </div>

          {/* Tasks Table */}
          <section style={{ ...cardStyle, marginTop: 10, display: "block" }}>
            <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 6 }}>
              {/* Toggle between the regular task list and the recurring task list.  These
              act like headings but function as interactive buttons. */}
              <Toggle active={!showRecurring} onClick={() => setShowRecurring(false)}>Tasks</Toggle>
              <Toggle active={showRecurring} onClick={() => setShowRecurring(true)}>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '2px 10px', borderRadius: 999, background: 'linear-gradient(90deg, #0ea5e9, #a855f7, #f43f5e)', color: '#fff', fontWeight: 700, boxShadow: '0 1px 2px rgba(0,0,0,.15)' }}>
                  🔁 Recurring Tasks
                </span>
              </Toggle>
            </div>
            <div className="table-wrapper" ref={tableWrapperRef} onScroll={onTableScroll}>
              <table style={{ width: "100%", fontSize: 13, borderCollapse: "collapse", minWidth: 900 }}>
                <thead>
                  <tr style={{ color: "#64748b", textAlign: "left" }}>
                    <th style={thSlim}><input type={'checkbox'} aria-label="Select all" checked={listForDisplay.length > 0 && listForDisplay.every(t => selectedTasks.has(t.id))} onChange={(e) => { e.stopPropagation(); if (e.target.checked) { setSelectedTasks(new Set(listForDisplay.map(t => t.id))); } else { setSelectedTasks(new Set()); } }} /></th>
                    <th style={thSlim}>#</th>
                    <th style={thSlim}>Client</th>
                    <th style={thSlim}>Dept</th>
                    <th style={thSlim}>Assignee</th>
                    <th style={{ textAlign: 'left' }}>
                      <button
                        onClick={() => toggleExpandAll(listForDisplay)}
                        style={{
                          border: 'none',
                          background: 'transparent',
                          cursor: 'pointer',
                          marginRight: 6,
                          fontSize: 12,
                          verticalAlign: 'middle'
                        }}
                        title="Expand / collapse all subtasks"
                      >
                        {(() => {
                          const parents = listForDisplay.filter(t => Array.isArray(t.subtasks) && t.subtasks.length > 0);
                          const allExpanded = parents.length > 0 && parents.every(t => expandedParents[t.id]);
                          return allExpanded ? '▼' : '▶';
                        })()}
                      </button>
                      Description
                    </th>
                    <th style={thSlim}>Due</th>
                    <th style={thSlim}>Status</th>
                    <th style={thSlim}>Invoice</th>
                    <th style={{ ...thSlim, textAlign: "right", paddingRight: 6 }}>Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {listForDisplay.map((t, idx) => {
                    const rowStyle = (t.is_overdue || t.status === "Overdue")
                      ? { background: "#fee2e2" }
                      : (t.status === "Completed" && t.invoice_status === "Paid")
                        ? { background: "#dcfce7" }
                        : (t.status === "Completed")
                          ? { background: "#fef9c3" }
                          : {};
                    // Determine if invoice has been issued.  Treat everything except 'Not Issued' as issued
                    // so that the drop‑down remains visible for statuses like 'N/A'.
                    const isIssued = t.invoice_status !== "Not Issued";
                    // Payment statuses to show in the drop‑down.  Exclude 'Cancelled' per requirements.
                    const payStatuses = ["Paid", "Unpaid", "Partially Paid", "N/A"];
                    const payValue = payStatuses.includes(t.invoice_status) ? t.invoice_status : "Unpaid";
                    return (
                      <tr key={t.id} style={{ borderTop: "1px solid #e2e8f0", ...rowStyle }} onClick={() => openEdit(t)} title="Click to edit">
                        <td style={{ ...tdSlim, width: 40 }} onClick={(e) => e.stopPropagation()}><input type={'checkbox'} checked={selectedTasks.has(t.id)} onChange={(e) => { e.stopPropagation(); const copy = new Set(selectedTasks); if (e.target.checked) copy.add(t.id); else copy.delete(t.id); setSelectedTasks(copy); }} /></td>
                        <td style={{ ...tdSlim, width: 34 }}>{idx + 1}</td>
                        <td style={tdSlim}>{clientsById[t.client_id]?.name || "—"}</td>
                        <td style={tdSlim}>{t.department}</td>
                        <td style={tdSlim}>
                          <span title={t.assignee || "Unassigned"}>
                            {t.assignee ? (
                              <span style={{ fontSize: 12, fontWeight: 500 }}>{t.assignee}</span>
                            ) : (
                              <span style={{ fontSize: 11, color: '#94a3b8', fontStyle: 'italic' }}>Unassigned</span>
                            )}
                          </span>
                        </td>
                        <td className="description-cell" style={tdSlim}>
                          {/* Priority icons before description */}
                          <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
                            {t.priority === 'Critical' && <span title="Critical Priority" style={{ color: '#991b1b', fontSize: '14px' }}>🔥</span>}
                            {t.priority === 'High' && <span title="High Priority" style={{ color: '#dc2626', fontSize: '14px' }}>⚡</span>}
                            <div className="clamp-3" style={{ fontWeight: 600 }}>{t.task_description}</div>
                          </div>
                          {t.sub_count?.total > 0 && (
                            <div style={{ fontSize: 11, color: "#64748b", marginTop: 2 }}>Subtasks: {t.sub_count.done}/{t.sub_count.total}</div>
                          )}

                          {/* Subtasks preview */}
                          {(() => {
                            const subsAll = Array.isArray(t.subtasks) ? t.subtasks : [];
                            let subs = subsAll;
                            // Dept filter on preview
                            if (filters?.department && filters.department !== "All") {
                              subs = subs.filter(s => s.department === filters.department);
                            }
                            // Respect non-owner visibility (fallback to isOwner if hasViewAllPermission is undefined)
                            const canViewAll = (typeof hasViewAllPermission !== 'undefined' ? hasViewAllPermission
                              : (typeof isOwner !== 'undefined' ? isOwner : false));
                            if (!canViewAll) {
                              const myDept = currentUser?.department;
                              subs = subs.filter(s => s.department === myDept);
                            }
                            if (subs.length === 0) return null;
                            return (
                              <div style={{ marginTop: 4 }}>
                                {subs.slice(0, 3).map((s, i) => (
                                  <div key={i} style={{ fontSize: 12, color: "#0f172a" }}>
                                    • {(s.title || s.task_description || "").trim()}
                                  </div>
                                ))}
                                {subs.length > 3 && (
                                  <div style={{ fontSize: 11, color: "#64748b" }}>+{subs.length - 3} more…</div>
                                )}
                              </div>
                            );
                          })()}

                          <div className="status-inline-row" onClick={(e) => e.stopPropagation()} style={{ display: 'flex', alignItems: 'center', gap: '16px', marginTop: 16, whiteSpace: 'nowrap' }}>
                            <label><input type="checkbox" checked={!!t.quote_approved} onChange={(e) => upsertTask({ ...t, quote_approved: e.target.checked })} /> Quote Approved</label>
                            <label><input type="checkbox" checked={!!t.advance_received} onChange={(e) => upsertTask({ ...t, advance_received: e.target.checked })} /> Advance Received</label>
                            <label><input
                              type="checkbox"
                              checked={t.status === 'In Progress' || t.status === 'Completed'}
                              onChange={(e) => {
                                const startedNow = e.target.checked;
                                if (t.status === 'Completed') { return; }
                                upsertTask({ ...t, status: startedNow ? 'In Progress' : 'Not Started' });
                              }}
                            /> Started</label>
                            <label><input
                              type="checkbox"
                              checked={t.status === 'Completed'}
                              onChange={(e) => {
                                if (e.target.checked) {
                                  upsertTask({ ...t, status: 'Completed', completion_date: todayISO() });
                                } else {
                                  // On uncheck, do NOT auto-check "Started"; revert to Not Started.
                                  upsertTask({ ...t, status: 'In Progress', completion_date: null });
                                }
                              }}
                            /> Completed</label>
                          </div>
                        </td>

                        {/* Due date - more prominent now */}
                        <td style={{ ...tdSlim, fontWeight: t.is_overdue ? 700 : 400, color: t.is_overdue ? '#dc2626' : (t.status === 'Completed' ? '#16a34a' : '#0f172a') }}>
                          {t.due_date ? fmtDDMMYY(t.due_date) : "—"}
                          {t.start_date && (
                            <div style={{ fontSize: 10, color: '#64748b', marginBottom: 2 }}>Start: {fmtDDMMYY(t.start_date)}</div>
                          )}
                          {t.completion_date && (
                            <div style={{ fontSize: 10, color: '#16a34a', marginBottom: 8 }}>Done: {fmtDDMMYY(t.completion_date)}</div>
                          )}
                        </td>

                        {/* Status cell - consolidated */}
                        <td style={tdSlim}>
                          <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
                            <span style={{
                              fontSize: 12,
                              fontWeight: 600,
                              color: t.status === 'Completed' ? '#16a34a' :
                                t.is_overdue ? '#dc2626' :
                                  t.status === 'In Progress' ? '#2563eb' : '#64748b'
                            }}>
                              {t.status || 'Not Started'}
                              {t.is_overdue && !['Completed', 'Cancelled'].includes(t.status) && ' ⚠️'}
                            </span>
                            <span style={{ fontSize: 10, color: '#64748b' }}>
                              {t.priority} Priority
                            </span>
                          </div>
                        </td>

                        {/* Invoice cell - same as before but slightly adjusted */}
                        <td style={tdSlim} onClick={(e) => e.stopPropagation()}>{t.invoice_status && t.invoice_status !== "Not Issued" ? (
                          <span title="Invoiced" style={{ color: "#16a34a", fontWeight: 600 }}>🧾 Invoiced</span>
                        ) : (
                          <span title="Not Invoiced" style={{ color: "#f59e0b", fontWeight: 600 }}>⏳ Not Invoiced</span>
                        )}
                        </td>

                        <td style={{ ...tdSlim, textAlign: "right", paddingRight: 6 }} onClick={(e) => e.stopPropagation()}>
                          {canEditTask(t) && (<><span>{canManageInvoices() && (
                            <button type="button" aria-label="Invoice Oversight" onClick={() => openInvoiceSmart(t)} style={btnSmall}>👁️</button>
                          )}</span><span><button type="button" aria-label="Duplicate task" onClick={(e) => { e.stopPropagation(); duplicateTask(t); }} style={btnSmall}>⎘</button> {canDeleteTask() && (<button type="button" aria-label="Delete task" onClick={() => deleteTask(t.id)} style={btnDangerIconSmall}>🗑️</button>)}</span>
                          </>)}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
                {filtered.length === 0 && (
                  <tbody>
                    <tr>
                      <td colSpan="11" style={{ textAlign: 'center', padding: '20px', color: '#64748b' }}>
                        No tasks found matching your filters.
                      </td>
                    </tr>
                  </tbody>
                )}
              </table>
            </div>
          </section>


          {/* Invoice Oversight Panel (restricted) */}
          {showInvoicePanel && canManageInvoices() && (
            <div className="confirmation-modal" onClick={() => setShowInvoicePanel(false)}>
              <div className="confirmation-content" style={{ width: 'min(1350px, 98vw)', maxHeight: '92vh', overflow: 'auto', position: 'relative' }} onClick={(e) => e.stopPropagation()}>
                <button type="button" aria-label="Close" onClick={() => setShowInvoicePanel(false)} style={{ position: 'absolute', top: 8, right: 8, background: 'transparent', border: 'none', fontSize: 18, cursor: 'pointer' }}>✖</button>
                <h3 style={{ marginTop: 0 }}>Invoice Oversight</h3>
                <p style={{ marginTop: 4, color: '#475569', fontSize: 12 }}>Review completed tasks, ensure invoices are issued, posted to QuickBooks, and amounts are recorded.</p>

                {/* Toolbar: Department + Date Range + KPIs */}
                <div style={{ position: 'sticky', top: -16, background: '#fff', zIndex: 11, padding: '8px 0', marginBottom: 6, display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid #f1f5f9' }}>
                  {/* All filters in one compact row */}
                  <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
                    {/* Department */}
                    <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                      <span style={{ fontSize: 12, color: '#475569', whiteSpace: 'nowrap' }}>Dept:</span>
                      <select
                        value={invoiceDept}
                        onChange={(e) => setInvoiceDept(e.target.value)}
                        style={{ ...selectStyleXS, width: 110 }}
                      >
                        {departmentOptions.map(d => <option key={d} value={d}>{d}</option>)}
                      </select>
                    </div>

                    {/* Client */}
                    <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                      <span style={{ fontSize: 12, color: '#475569', whiteSpace: 'nowrap' }}>Client:</span>
                      <select
                        value={invoiceClient}
                        onChange={(e) => setInvoiceClient(e.target.value)}
                        style={{ ...selectStyleXS, width: 120 }}
                      >
                        <option value="All">All</option>
                        {Array.from(new Set((state.tasks || []).map(t => t.client_id).filter(Boolean))).map(cid => (
                          <option key={cid} value={cid}>
                            {clientsById[cid]?.name || cid}
                          </option>
                        ))}
                      </select>
                    </div>

                    {/* Invoice Status */}
                    <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                      <span style={{ fontSize: 12, color: '#475569', whiteSpace: 'nowrap' }}>Status:</span>
                      <select
                        value={invoiceStatusFilter}
                        onChange={(e) => setInvoiceStatusFilter(e.target.value)}
                        style={{ ...selectStyleXS, width: 110 }}
                      >
                        {['All', 'Unpaid', 'Paid', 'Partially Paid', 'N/A'].map(s => <option key={s} value={s}>{s}</option>)}
                      </select>
                    </div>

                    {/* Date Range */}
                    <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                      <span style={{ fontSize: 12, color: '#475569', whiteSpace: 'nowrap' }}>Dates:</span>
                      <input
                        type="date"
                        value={invoiceFrom}
                        onChange={(e) => { setQuickRange("none"); setInvoiceFrom(e.target.value) }}
                        style={{ ...inputStyle, width: 100, padding: '4px 6px', fontSize: 11 }}
                      />
                      <span style={{ fontSize: 11, color: '#94a3b8' }}>to</span>
                      <input
                        type="date"
                        value={invoiceTo}
                        onChange={(e) => { setQuickRange("none"); setInvoiceTo(e.target.value) }}
                        style={{ ...inputStyle, width: 100, padding: '4px 6px', fontSize: 11 }}
                      />
                      <button
                        type="button"
                        onClick={() => { setInvoiceFrom(''); setInvoiceTo(''); }}
                        style={{ ...btnSmall, padding: '4px 6px', fontSize: 11 }}
                      >
                        Clear
                      </button>
                    </div>

                    {/* Quick Range */}
                    <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                      <span style={{ fontSize: 12, color: '#475569', whiteSpace: 'nowrap' }}>Range:</span>
                      <select value={quickRange} onChange={(e) => setQuickRange(e.target.value)} style={{ ...selectStyleXS, width: 110, fontSize: 11 }}>
                        <option value="all">All</option>
                        <option value="today">Today</option>
                        <option value="week">This Week</option>
                        <option value="month">This Month</option>
                        <option value="year">This Year</option>
                        <option value="last_week">Last Week</option>
                        <option value="last_month">Last Month</option>
                        <option value="last_year">Last Year</option>
                      </select>
                    </div>

                    {/* Search Bar */}
                    <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                      <span style={{ fontSize: 12, color: '#475569', whiteSpace: 'nowrap' }}>Search:</span>
                      <div style={{ position: 'relative' }}>
                        <input
                          type="text"
                          value={invoiceSearch}
                          onChange={(e) => setInvoiceSearch(e.target.value)}
                          placeholder="Client, Task..."
                          style={{
                            padding: '4px 8px 4px 28px',
                            border: '1px solid #cbd5e1',
                            borderRadius: '6px',
                            fontSize: '11px',
                            width: '80px'
                          }}
                        />
                        <span style={{ position: 'absolute', left: '8px', top: '50%', transform: 'translateY(-50%)', fontSize: '12px', color: '#64748b' }}>
                        </span>
                        {invoiceSearch && (
                          <button
                            onClick={() => setInvoiceSearch('')}
                            style={{
                              position: 'absolute',
                              right: '6px',
                              top: '50%',
                              transform: 'translateY(-50%)',
                              background: 'transparent',
                              border: 'none',
                              color: '#64748b',
                              cursor: 'pointer',
                              fontSize: '12px',
                              padding: '0'
                            }}
                          >
                            ✕
                          </button>
                        )}
                      </div>
                    </div>
                  </div>
                </div>

                <div style={{ border: '1px solid #e5e7eb', borderRadius: 8, padding: 8, marginTop: 8 }}>
                  <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
                    <thead>
                      <tr style={{ textAlign: 'left', color: '#64748b', position: 'sticky', top: 38, background: '#fff', zIndex: 10 }}>
                        <th style={{ padding: '6px', background: '#f8fafc' }}>Client</th>
                        <th style={{ textAlign: 'left', background: '#f8fafc' }}>
                          <button
                            onClick={() => toggleExpandAll(listForDisplay)}
                            style={{
                              border: 'none',
                              background: 'transparent',
                              cursor: 'pointer',
                              marginRight: 6,
                              fontSize: 12,
                              verticalAlign: 'middle'
                            }}
                            title="Expand / collapse all subtasks"
                          >
                            {(() => {
                              const parents = listForDisplay.filter(t => Array.isArray(t.subtasks) && t.subtasks.length > 0);
                              const allExpanded = parents.length > 0 && parents.every(t => expandedParents[t.id]);
                              return allExpanded ? '▼' : '▶';
                            })()}
                          </button>
                          Description
                        </th>
                        <th style={{ padding: '6px', background: '#f8fafc' }}>Completed</th>
                        <th style={{ padding: '6px', background: '#f8fafc' }}>Issued</th>
                        <th style={{ padding: '6px', background: '#f8fafc' }}>Status</th>
                        <th style={{ padding: '6px', background: '#f8fafc' }}>Aging Bucket</th>
                        <th style={{ padding: '6px', background: '#f8fafc' }}>Days to Pay</th>
                        <th style={{ padding: '6px', background: '#f8fafc' }}>QB Posted</th>
                        <th style={{ padding: '6px', textAlign: 'right', background: '#f8fafc' }}>Amount</th>
                        <th style={{ padding: '6px', textAlign: 'right', background: '#f8fafc' }}>Paid</th>
                        <th style={{ padding: '6px', textAlign: 'right', background: '#f8fafc' }}>Balance</th>
                        <th style={{ padding: '6px', textAlign: 'center', background: '#f8fafc' }}>Reminders</th>

                      </tr>
                    </thead>
                    <tbody>
                      {state.tasks
                        .filter(t => t.status === "Completed" || ((t.subtasks || []).some(s => s && (s.status === 'Completed' || s.done))))
                        .filter(t => invoiceDept === "All" || t.department === invoiceDept)
                        .filter(t => (invoiceStatusFilter === 'All') ? true : (
                          (t.invoice_status === invoiceStatusFilter) ||
                          ((t.subtasks || []).some(s => s && s.invoice_status === invoiceStatusFilter))
                        ))
                        .filter(invoiceInRange)
                        .filter(t => invoiceClient === "All" || t.client_id === invoiceClient)
                        // Add this search filter:
                        .filter(t => {
                          if (!invoiceSearch.trim()) return true;
                          const search = invoiceSearch.toLowerCase();

                          // Search in client name
                          const clientName = (clientsById[t.client_id]?.name || '').toLowerCase();
                          if (clientName.includes(search)) return true;

                          // Search in task description
                          const taskDesc = (t.task_description || '').toLowerCase();
                          if (taskDesc.includes(search)) return true;

                          // Search in invoice amount
                          const amount = (t.invoice_amount || '').toString();
                          if (amount.includes(search)) return true;

                          // Search in subtasks
                          if (t.subtasks && t.subtasks.some(s => {
                            const subDesc = (s.title || s.task_description || '').toLowerCase();
                            return subDesc.includes(search);
                          })) return true;

                          return false;
                        })
                        .sort((a, b) => (clientsById[a.client_id]?.name || '').localeCompare(clientsById[b.client_id]?.name || ''))
                        .map(t => {
                          const client = clientsById[t.client_id]?.name || "—";
                          const hasCompletedSubs = (t.subtasks || []).some(s => s && (s.status === 'Completed' || s.done));
                          const parentCompleted = t.status === "Completed";
                          return (
                            <>
                              {parentCompleted && (
                                (invoiceStatusFilter === 'All' || (t.invoice_status === invoiceStatusFilter)) &&
                                ((!invoiceFrom && !invoiceTo) || (
                                  t.invoice_issued && t.invoice_issued_date && ((() => {
                                    const dt = toDate(String(t.invoice_issued_date));
                                    if (invoiceFrom) { const from = toDate(invoiceFrom); if (dt < from) return false; }
                                    if (invoiceTo) { const to = toDate(invoiceTo); to.setHours(23, 59, 59, 999); if (dt > to) return false; }
                                    return true;
                                  })())
                                ))
                              ) && (
                                  <tr key={t.id} style={{ borderTop: '1px solid #e5e7eb' }}>
                                    <td style={{ padding: '6px', textAlign: 'left' }}>{client}</td>


                                    <td style={{ padding: '6px', textAlign: 'left' }}>
                                      <div style={{ display: 'flex', alignItems: 'flex-start', gap: '6px' }}>
                                        {(t.subtasks && t.subtasks.length > 0) && (
                                          <button
                                            onClick={(e) => {
                                              e.stopPropagation();
                                              setExpandedParents(p => ({ ...p, [t.id]: !p[t.id] }));
                                            }}
                                            style={{
                                              border: 'none',
                                              background: 'transparent',
                                              cursor: 'pointer',
                                              fontSize: 12,
                                              flexShrink: 0,
                                              marginTop: '2px'
                                            }}
                                            title="Expand / collapse subtasks"
                                          >
                                            {expandedParents[t.id] ? '▼' : '▶'}
                                          </button>
                                        )}
                                        <button
                                          onClick={(e) => {
                                            e.stopPropagation();
                                            openEdit(t); // This opens the edit form
                                          }}
                                          style={{
                                            border: 'none',
                                            background: 'transparent',
                                            cursor: 'pointer',
                                            textAlign: 'left',
                                            color: '#1e40af',
                                            fontWeight: 500,
                                            padding: '4px',
                                            borderRadius: '4px',
                                            flexGrow: 1
                                          }}
                                          title="Click to edit this task"
                                          onMouseOver={(e) => e.currentTarget.style.background = '#f0f9ff'}
                                          onMouseOut={(e) => e.currentTarget.style.background = 'transparent'}
                                        >
                                          {t.task_description}
                                        </button>
                                      </div>
                                    </td>

                                    <td style={{ padding: '6px' }}>{t.completion_date ? fmtDDMMYY(t.completion_date) : "—"}</td>
                                    <td style={{ padding: '6px' }}>
                                      <input
                                        type="checkbox"
                                        checked={!!t.invoice_issued}
                                        onChange={(e) => {
                                          const issued = e.target.checked;
                                          upsertTask({
                                            ...t,
                                            invoice_issued: issued,
                                            invoice_status: issued ? (t.invoice_status || 'Unpaid') : null,
                                            invoice_issued_date: issued ? todayISO() : null
                                          });
                                        }}
                                      />
                                      {t.invoice_issued_date && (
                                        <div style={{ fontSize: 10, color: '#64748b' }}>
                                          Issued: {fmtDDMMYY(String(t.invoice_issued_date))}
                                        </div>
                                      )}
                                    </td>
                                    <td style={{ padding: '6px' }}>
                                      <select
                                        value={t.invoice_status || 'Unpaid'}
                                        onChange={(e) => {
                                          const v = e.target.value;
                                          upsertTask({
                                            ...t,
                                            invoice_status: v,
                                            invoice_paid_date: (v === 'Paid' ? (t.invoice_paid_date || todayISO()) : null),
                                            invoice_na: v === 'N/A',
                                            invoice_issued: v === 'N/A' ? false : t.invoice_issued
                                          });
                                        }}
                                        style={selectStyleXS}
                                        disabled={!t.invoice_issued}
                                      >
                                        {['Unpaid', 'Paid', 'Partially Paid', 'N/A'].map(s => <option key={s}>{s}</option>)}
                                      </select>
                                      {t.invoice_paid_date && (
                                        <div style={{ fontSize: 10, color: '#64748b' }}>
                                          Paid: {fmtDDMMYY(String(t.invoice_paid_date))}
                                          {t.invoice_issued_date && (
                                            <span> · {Math.round((toDate(String(t.invoice_paid_date)) - toDate(String(t.invoice_issued_date))) / 86400000)}d</span>
                                          )}
                                        </div>
                                      )}
                                    </td>
                                    <td style={{ padding: '6px' }}>
                                      {(() => {
                                        if (t.invoice_status === 'N/A') return <span style={{ color: '#64748b' }}>N/A</span>;
                                        if (!t.invoice_issued_date) return '—';

                                        const issuedDate = toDate(String(t.invoice_issued_date));
                                        const today = new Date();
                                        const daysAging = Math.round((today - issuedDate) / (1000 * 60 * 60 * 24));

                                        let bucketColor = '#16a34a'; // Green for 0-30
                                        let bucketText = '0-30 days';

                                        if (daysAging > 90) {
                                          bucketColor = '#dc2626';
                                          bucketText = '90+ days';
                                        } else if (daysAging > 60) {
                                          bucketColor = '#ea580c';
                                          bucketText = '61-90 days';
                                        } else if (daysAging > 30) {
                                          bucketColor = '#d97706';
                                          bucketText = '31-60 days';
                                        }

                                        return (
                                          <div>
                                            <div style={{ fontSize: 11, fontWeight: 600, color: bucketColor }}>{bucketText}</div>
                                            <div style={{ fontSize: 10, color: '#64748b' }}>{daysAging} days</div>
                                          </div>
                                        );
                                      })()}
                                    </td>
                                    <td style={{ padding: '6px' }}>
                                      {t.invoice_status === 'N/A' ? '—' : ((t.invoice_paid_date && t.invoice_issued_date) ? Math.max(0, Math.round((toDate(String(t.invoice_paid_date)) - toDate(String(t.invoice_issued_date))) / 86400000)) : '—')}
                                    </td>
                                    <td style={{ padding: '6px', textAlign: 'center' }}>
                                      <input
                                        type="checkbox"
                                        checked={!!t.qb_posted}
                                        onChange={(e) => upsertTask({ ...t, qb_posted: e.target.checked })}
                                      />
                                    </td>
                                    <td style={{ padding: '6px', textAlign: 'right' }}>
                                      <input
                                        type="number"
                                        step="0.01"
                                        value={t.invoice_amount ?? 0}
                                        onChange={(e) => {
                                          const val = e.target.value === "" ? "" : Number(e.target.value);
                                          upsertTask({ ...t, invoice_amount: val });
                                        }}
                                        style={{ ...inputStyle, width: 110, textAlign: 'right' }}
                                      />
                                    </td>
                                    <td style={{ padding: '6px', textAlign: 'right' }}>
                                      <input
                                        type="number"
                                        step="0.01"
                                        value={t.paid_amount || 0}
                                        onChange={(e) => {
                                          const val = e.target.value === "" ? "" : Number(e.target.value);
                                          upsertTask({ ...t, paid_amount: val });
                                        }}
                                        style={{ ...inputStyle, width: 90, textAlign: 'right' }}
                                      />
                                    </td>
                                    <td style={{ padding: '6px', textAlign: 'right', fontWeight: 600, color: '#dc2626' }}>
                                      {computeBalance(t).toLocaleString()}
                                    </td>
                                    <td style={{ padding: '6px', textAlign: 'center' }}>
                                      <button
                                        type="button"
                                        onClick={(e) => {
                                          e.stopPropagation();
                                          setSelectedTaskForReminders(t);
                                          setSelectedSubtaskForReminders(null);
                                          setSelectedSubtaskIndex(null);
                                        }}
                                        style={{
                                          background: '#3b82f6',
                                          border: 'none',
                                          color: 'white',
                                          padding: '4px 8px',
                                          borderRadius: '6px',
                                          fontSize: '11px',
                                          cursor: 'pointer',
                                          display: 'flex',
                                          alignItems: 'center',
                                          gap: '4px'
                                        }}
                                        title="View/Add Reminders"
                                      >
                                        🔔
                                        <span>{(t.reminders || []).length}</span>
                                      </button>
                                    </td>
                                  </tr>
                                )}

                              {expandedParents[t.id] && (t.subtasks || []).length > 0 && (
                                (t.subtasks || []).filter(s => (invoiceStatusFilter === 'All' ? true : (s && ((s.invoice_status || s.status) === invoiceStatusFilter)))).map((s, origIndex) => ({ s, origIndex })).filter(({ s }) => s && (s.status === 'Completed' || s.done)).map(({ s, origIndex }, si) => (
                                  <tr key={t.id + '-sub-' + origIndex} style={{ borderTop: '1px dashed #e5e7eb', background: '#fafafa' }} onClick={(e) => e.stopPropagation()}>
                                    <td style={{ padding: '6px', textAlign: 'left' }}>{clientsById[t.client_id]?.name || "—"}</td>
                                    <td style={{ padding: '6px' }}>
                                      <div style={{ display: 'flex', alignItems: 'center' }}>
                                        <span style={{ opacity: 0.7, marginRight: 6 }}>↳</span>
                                        <button
                                          onClick={(e) => {
                                            e.stopPropagation();
                                            openEdit(t); // Opens the parent task (which contains the subtask)
                                          }}
                                          style={{
                                            border: 'none',
                                            background: 'transparent',
                                            cursor: 'pointer',
                                            textAlign: 'left',
                                            color: '#1e40af',
                                            fontWeight: 500,
                                            padding: '4px',
                                            borderRadius: '4px',
                                            flexGrow: 1
                                          }}
                                          title="Click to edit this subtask (opens parent task)"
                                          onMouseOver={(e) => e.currentTarget.style.background = '#f0f9ff'}
                                          onMouseOut={(e) => e.currentTarget.style.background = 'transparent'}
                                        >
                                          {(s.title || s.task_description || s.task || ('Subtask ' + (si + 1)))}
                                        </button>
                                      </div>
                                    </td>
                                    <td style={{ padding: '6px' }}>{s.completion_date ? fmtDDMMYY(String(s.completion_date)) : "—"}</td>
                                    <td style={{ padding: '6px' }} onClick={(e) => e.stopPropagation()}>
                                      {canManageInvoices() ? (
                                        <div>
                                          <input
                                            type="checkbox"
                                            checked={!!s.invoice_issued}
                                            onChange={(e) => {
                                              const issued = e.target.checked;
                                              const subs = (t.subtasks || []).filter(s => (invoiceStatusFilter === 'All' ? true : (s && ((s.invoice_status || s.status) === invoiceStatusFilter)))).map((sub, j) => j === origIndex ? ({
                                                ...sub,
                                                invoice_issued: issued,
                                                invoice_status: issued ? (sub.invoice_status || 'Unpaid') : null,
                                                invoice_issued_date: issued ? todayISO() : null
                                              }) : sub);
                                              upsertTask({ ...t, subtasks: subs });
                                            }}
                                          />
                                          {s.invoice_issued_date && (
                                            <div style={{ fontSize: 10, color: '#64748b' }}>
                                              Issued: {fmtDDMMYY(String(s.invoice_issued_date))}
                                            </div>
                                          )}
                                        </div>
                                      ) : (
                                        <div style={{ fontSize: 12, color: '#475569' }}>{s.invoice_issued ? 'Issued' : 'Not Issued'}</div>
                                      )}
                                    </td>
                                    <td style={{ padding: '6px' }} onClick={(e) => e.stopPropagation()}>
                                      {canManageInvoices() ? (
                                        <select
                                          value={s.invoice_status || 'Unpaid'}
                                          onChange={(e) => {
                                            const subs = (t.subtasks || []).filter(s => (invoiceStatusFilter === 'All' ? true : (s && ((s.invoice_status || s.status) === invoiceStatusFilter)))).map((sub, j) => j === origIndex ? ({ ...sub, invoice_status: e.target.value }) : sub);
                                            upsertTask({ ...t, subtasks: subs });
                                          }}
                                          style={selectStyleXS}
                                          disabled={!s.invoice_issued}
                                        >
                                          {['Unpaid', 'Paid', 'Partially Paid'].map(st => <option key={st}>{st}</option>)}
                                        </select>
                                      ) : (
                                        <span style={{ fontSize: 12 }}>{s.invoice_issued ? (s.invoice_status || 'Unpaid') : '—'}</span>
                                      )}
                                    </td>
                                    <td style={{ padding: '6px' }}>
                                      {(() => {
                                        if (s.invoice_status === 'N/A') return <span style={{ color: '#64748b' }}>N/A</span>;
                                        if (!s.invoice_issued_date) return '—';

                                        const issuedDate = toDate(String(s.invoice_issued_date));
                                        const today = new Date();
                                        const daysAging = Math.round((today - issuedDate) / (1000 * 60 * 60 * 24));

                                        let bucketColor = '#16a34a'; // Green for 0-30
                                        let bucketText = '0-30 days';

                                        if (daysAging > 90) {
                                          bucketColor = '#dc2626';
                                          bucketText = '90+ days';
                                        } else if (daysAging > 60) {
                                          bucketColor = '#ea580c';
                                          bucketText = '61-90 days';
                                        } else if (daysAging > 30) {
                                          bucketColor = '#d97706';
                                          bucketText = '31-60 days';
                                        }

                                        return (
                                          <div>
                                            <div style={{ fontSize: 11, fontWeight: 600, color: bucketColor }}>{bucketText}</div>
                                            <div style={{ fontSize: 10, color: '#64748b' }}>{daysAging} days</div>
                                          </div>
                                        );
                                      })()}
                                    </td>
                                    <td style={{ padding: '6px' }}>
                                      {(() => {
                                        if (s.invoice_issued_date && s.completion_date) {
                                          const days = Math.floor((toDate(String(s.invoice_issued_date)) - toDate(String(s.completion_date))) / (1000 * 60 * 60 * 24));
                                          return isNaN(days) ? '—' : days;
                                        }
                                        return '—';
                                      })()}
                                    </td>
                                    <td style={{ padding: '6px' }} onClick={(e) => e.stopPropagation()}>
                                      {canManageInvoices() ? (
                                        <input
                                          type="checkbox"
                                          checked={!!s.qb_posted}
                                          onChange={(e) => {
                                            const subs = (t.subtasks || []).filter(s => (invoiceStatusFilter === 'All' ? true : (s && ((s.invoice_status || s.status) === invoiceStatusFilter)))).map((sub, j) => j === origIndex ? ({ ...sub, qb_posted: e.target.checked }) : sub);
                                            upsertTask({ ...t, subtasks: subs });
                                          }}
                                        />
                                      ) : (
                                        <span style={{ fontSize: 12 }}>{s.qb_posted ? 'Yes' : 'No'}</span>
                                      )}
                                    </td>
                                    <td style={{ padding: '6px', textAlign: 'right' }} onClick={(e) => e.stopPropagation()}>
                                      {canManageInvoices() ? (
                                        <input
                                          type="number"
                                          value={Number(s.invoice_amount || 0)}
                                          onChange={(e) => {
                                            const subs = (t.subtasks || []).filter(s => (invoiceStatusFilter === 'All' ? true : (s && ((s.invoice_status || s.status) === invoiceStatusFilter)))).map((sub, j) => j === origIndex ? ({ ...sub, invoice_amount: Number(e.target.value || 0) }) : sub);
                                            upsertTask({ ...t, subtasks: subs });
                                          }}
                                          style={{ width: 90 }}
                                          min="0"
                                          step="0.01"
                                        />
                                      ) : (
                                        <span>{Number(s.invoice_amount || 0).toLocaleString()}</span>
                                      )}
                                    </td>
                                    {/* PAID AMOUNT for subtask */}
                                    <td style={{ padding: '6px', textAlign: 'right' }} onClick={(e) => e.stopPropagation()}>
                                      {canManageInvoices() ? (
                                        <input
                                          type="number"
                                          step="0.01"
                                          value={s.paid_amount || 0}
                                          onChange={(e) => {
                                            const val = e.target.value === "" ? "" : Number(e.target.value);
                                            const subs = (t.subtasks || []).map((sub, j) =>
                                              j === origIndex ? { ...sub, paid_amount: val } : sub
                                            );
                                            upsertTask({ ...t, subtasks: subs });
                                          }}
                                          style={{ ...inputStyle, width: 90, textAlign: 'right' }}
                                        />
                                      ) : (
                                        <span>{Number(s.paid_amount || 0).toLocaleString()}</span>
                                      )}
                                    </td>

                                    {/* BALANCE for subtask */}
                                    <td style={{ padding: '6px', textAlign: 'right', fontWeight: 600, color: '#dc2626' }}>
                                      {(() => {
                                        const total = Number(s.invoice_amount) || 0;
                                        const paid = Number(s.paid_amount) || 0;
                                        const balance = total - paid;
                                        return balance < 0 ? 0 : balance;
                                      })().toLocaleString()}
                                    </td>
                                    <td style={{ padding: '6px', textAlign: 'center' }}>
                                      <button
                                        type="button"
                                        onClick={(e) => {
                                          e.stopPropagation();
                                          setSelectedTaskForReminders(t);
                                          setSelectedSubtaskForReminders(s);
                                          setSelectedSubtaskIndex(origIndex);
                                        }}
                                        style={{
                                          background: '#3b82f6',
                                          border: 'none',
                                          color: 'white',
                                          padding: '4px 8px',
                                          borderRadius: '6px',
                                          fontSize: '11px',
                                          cursor: 'pointer',
                                          display: 'flex',
                                          alignItems: 'center',
                                          gap: '4px'
                                        }}
                                        title="View/Add Reminders"
                                      >
                                        🔔
                                        <span>{(s.reminders || []).length}</span>
                                      </button>
                                    </td>
                                  </tr>
                                ))
                              )}
                            </>
                          );
                        })}
                    </tbody>
                    <tfoot>
                      <tr style={{ borderTop: '2px solid #e5e7eb', background: '#f8fafc', fontWeight: 600 }}>
                        <td style={{ padding: '8px' }} colSpan={8}>Total</td> {/* Changed from 9 to 7 */}
                        <td style={{ padding: '8px', textAlign: 'right' }}>
                          {(() => {
                            const inRangeMain = (t) => {
                              if (!invoiceFrom && !invoiceTo) return true;
                              if (!t || !t.invoice_issued || !t.invoice_issued_date) return false;
                              const dt = toDate(String(t.invoice_issued_date));
                              if (invoiceFrom) { const from = toDate(invoiceFrom); if (dt < from) return false; }
                              if (invoiceTo) { const to = toDate(invoiceTo); to.setHours(23, 59, 59, 999); if (dt > to) return false; }
                              return true;
                            };
                            const inRangeSub = (s) => {
                              if (!invoiceFrom && !invoiceTo) return true;
                              if (!s || !s.invoice_issued || !s.invoice_issued_date) return false;
                              const dt = toDate(String(s.invoice_issued_date));
                              if (invoiceFrom) { const from = toDate(invoiceFrom); if (dt < from) return false; }
                              if (invoiceTo) { const to = toDate(invoiceTo); to.setHours(23, 59, 59, 999); if (dt > to) return false; }
                              return true;
                            };
                            const statusOkMain = (t) => invoiceStatusFilter === 'All' ? true : (t.invoice_status === invoiceStatusFilter);
                            const statusOkSub = (s) => invoiceStatusFilter === 'All' ? true : (s.invoice_status === invoiceStatusFilter);
                            const list = state.tasks
                              .filter(t => t.status === "Completed" || ((t.subtasks || []).some(s => s && (s.status === 'Completed' || s.done))))
                              .filter(t => invoiceDept === "All" || t.department === invoiceDept)
                              .filter(t => invoiceClient === "All" || t.client_id === invoiceClient)
                              .filter(t => {
                                if (!invoiceSearch.trim()) return true;
                                const search = invoiceSearch.toLowerCase();
                                const clientName = (clientsById[t.client_id]?.name || '').toLowerCase();
                                const taskDesc = (t.task_description || '').toLowerCase();
                                const amount = (t.invoice_amount || '').toString();

                                return clientName.includes(search) ||
                                  taskDesc.includes(search) ||
                                  amount.includes(search) ||
                                  (t.subtasks && t.subtasks.some(s => {
                                    const subDesc = (s.title || s.task_description || '').toLowerCase();
                                    return subDesc.includes(search);
                                  }));
                              });
                            const total = list.reduce((sum, t) => {
                              let add = 0;
                              if (t.invoice_issued && inRangeMain(t) && statusOkMain(t)) {
                                add += (Number(t.invoice_amount) || 0);
                              }
                              add += (t.subtasks || []).reduce((ss, s) => {
                                const subCompleted = s && (s.status === 'Completed' || s.done);
                                return ss + (subCompleted && s.invoice_issued && inRangeSub(s) && statusOkSub(s) ? (Number(s.invoice_amount) || 0) : 0);
                              }, 0);
                              return sum + add;
                            }, 0);
                            return total.toLocaleString();
                          })()} <span style={{ color: '#64748b' }}>PKR</span>
                        </td>
                        <td style={{ padding: '8px', textAlign: 'right' }}>
                          {(() => {
                            const inRangeMain = (t) => {
                              if (!invoiceFrom && !invoiceTo) return true;
                              if (!t || !t.invoice_issued || !t.invoice_issued_date) return false;
                              const dt = toDate(String(t.invoice_issued_date));
                              if (invoiceFrom) { const from = toDate(invoiceFrom); if (dt < from) return false; }
                              if (invoiceTo) { const to = toDate(invoiceTo); to.setHours(23, 59, 59, 999); if (dt > to) return false; }
                              return true;
                            };
                            const inRangeSub = (s) => {
                              if (!invoiceFrom && !invoiceTo) return true;
                              if (!s || !s.invoice_issued || !s.invoice_issued_date) return false;
                              const dt = toDate(String(s.invoice_issued_date));
                              if (invoiceFrom) { const from = toDate(invoiceFrom); if (dt < from) return false; }
                              if (invoiceTo) { const to = toDate(invoiceTo); to.setHours(23, 59, 59, 999); if (dt > to) return false; }
                              return true;
                            };
                            const statusOkMain = (t) => invoiceStatusFilter === 'All' ? true : (t.invoice_status === invoiceStatusFilter);
                            const statusOkSub = (s) => invoiceStatusFilter === 'All' ? true : (s.invoice_status === invoiceStatusFilter);
                            const list = state.tasks
                              .filter(t => t.status === "Completed" || ((t.subtasks || []).some(s => s && (s.status === 'Completed' || s.done))))
                              .filter(t => invoiceDept === "All" || t.department === invoiceDept)
                              .filter(t => invoiceClient === "All" || t.client_id === invoiceClient)
                              .filter(t => {
                                if (!invoiceSearch.trim()) return true;
                                const search = invoiceSearch.toLowerCase();
                                const clientName = (clientsById[t.client_id]?.name || '').toLowerCase();
                                const taskDesc = (t.task_description || '').toLowerCase();
                                const amount = (t.invoice_amount || '').toString();

                                return clientName.includes(search) ||
                                  taskDesc.includes(search) ||
                                  amount.includes(search) ||
                                  (t.subtasks && t.subtasks.some(s => {
                                    const subDesc = (s.title || s.task_description || '').toLowerCase();
                                    return subDesc.includes(search);
                                  }));
                              });
                            const total = list.reduce((sum, t) => {
                              let add = 0;
                              if (t.invoice_issued && inRangeMain(t) && statusOkMain(t)) {
                                add += (Number(t.paid_amount) || 0);
                              }
                              add += (t.subtasks || []).reduce((ss, s) => {
                                const subCompleted = s && (s.status === 'Completed' || s.done);
                                return ss + (subCompleted && s.invoice_issued && inRangeSub(s) && statusOkSub(s) ? (Number(s.paid_amount) || 0) : 0);
                              }, 0);
                              return sum + add;
                            }, 0);
                            return total.toLocaleString();
                          })()} <span style={{ color: '#64748b' }}>PKR</span>
                        </td>
                        <td style={{ padding: '8px', textAlign: 'right' }}>
                          {(() => {
                            const inRangeMain = (t) => {
                              if (!invoiceFrom && !invoiceTo) return true;
                              if (!t || !t.invoice_issued || !t.invoice_issued_date) return false;
                              const dt = toDate(String(t.invoice_issued_date));
                              if (invoiceFrom) { const from = toDate(invoiceFrom); if (dt < from) return false; }
                              if (invoiceTo) { const to = toDate(invoiceTo); to.setHours(23, 59, 59, 999); if (dt > to) return false; }
                              return true;
                            };
                            const inRangeSub = (s) => {
                              if (!invoiceFrom && !invoiceTo) return true;
                              if (!s || !s.invoice_issued || !s.invoice_issued_date) return false;
                              const dt = toDate(String(s.invoice_issued_date));
                              if (invoiceFrom) { const from = toDate(invoiceFrom); if (dt < from) return false; }
                              if (invoiceTo) { const to = toDate(invoiceTo); to.setHours(23, 59, 59, 999); if (dt > to) return false; }
                              return true;
                            };
                            const statusOkMain = (t) => invoiceStatusFilter === 'All' ? true : (t.invoice_status === invoiceStatusFilter);
                            const statusOkSub = (s) => invoiceStatusFilter === 'All' ? true : (s.invoice_status === invoiceStatusFilter);
                            const list = state.tasks
                              .filter(t => t.status === "Completed" || ((t.subtasks || []).some(s => s && (s.status === 'Completed' || s.done))))
                              .filter(t => invoiceDept === "All" || t.department === invoiceDept)
                              .filter(t => invoiceClient === "All" || t.client_id === invoiceClient)
                              .filter(t => {
                                if (!invoiceSearch.trim()) return true;
                                const search = invoiceSearch.toLowerCase();
                                const clientName = (clientsById[t.client_id]?.name || '').toLowerCase();
                                const taskDesc = (t.task_description || '').toLowerCase();
                                const amount = (t.invoice_amount || '').toString();

                                return clientName.includes(search) ||
                                  taskDesc.includes(search) ||
                                  amount.includes(search) ||
                                  (t.subtasks && t.subtasks.some(s => {
                                    const subDesc = (s.title || s.task_description || '').toLowerCase();
                                    return subDesc.includes(search);
                                  }));
                              });
                            const total = list.reduce((sum, t) => {
                              let add = 0;
                              if (t.invoice_issued && inRangeMain(t) && statusOkMain(t)) {
                                const amount = Number(t.invoice_amount) || 0;
                                const paid = Number(t.paid_amount) || 0;
                                const balance = amount - paid;
                                add += (balance > 0 ? balance : 0);
                              }
                              add += (t.subtasks || []).reduce((ss, s) => {
                                const subCompleted = s && (s.status === 'Completed' || s.done);
                                if (subCompleted && s.invoice_issued && inRangeSub(s) && statusOkSub(s)) {
                                  const amount = Number(s.invoice_amount) || 0;
                                  const paid = Number(s.paid_amount) || 0;
                                  const balance = amount - paid;
                                  return ss + (balance > 0 ? balance : 0);
                                }
                                return ss;
                              }, 0);
                              return sum + add;
                            }, 0);
                            return total.toLocaleString();
                          })()} <span style={{ color: '#64748b' }}>PKR</span>
                        </td>
                      </tr>
                    </tfoot>
                  </table>
                </div>

                <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 10, alignItems: 'center' }}>
                  <div style={{ fontSize: 12, color: '#475569' }}>
                    <b>Total completed:</b>{" "}
                    {state.tasks.filter(t => t.status === "Completed").filter(t => invoiceDept === "All" || t.department === invoiceDept).filter(invoiceInRange).length} &middot;{" "}
                    <b>Not issued:</b>{" "}
                    {state.tasks.filter(t => t.status === "Completed").filter(t => invoiceDept === "All" || t.department === invoiceDept).filter(invoiceInRange).filter(t => !t.invoice_issued).length} &middot;{" "}
                    <b>Not posted to QB:</b>{" "}
                    {state.tasks.filter(t => t.status === "Completed").filter(t => invoiceDept === "All" || t.department === invoiceDept).filter(invoiceInRange).filter(t => !t.qb_posted).length}
                  </div>
                  <div style={{ fontSize: 13, display: "none" }}>
                    <b>Sum of amounts:</b>{" "}
                    {state.tasks.filter(t => t.status === "Completed").filter(t => invoiceDept === "All" || t.department === invoiceDept).filter(invoiceInRange).reduce((s, t) => s + (Number(t.invoice_amount) || 0), 0).toLocaleString()}{" "}
                    <span style={{ color: '#64748b' }}>PKR</span>
                  </div>
                </div>
                <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 12, gap: 8 }}>
                  <button type="button" onClick={() => setShowInvoicePanel(false)} style={btnPrimarySmall}>Close</button>
                </div>
              </div>
            </div>
          )}

          {/* --- IMPROVED BULK EDIT MODAL --- */}
          {showBulkEdit && (
            <div className="confirmation-modal" onClick={() => setShowBulkEdit(false)}>
              <div className="confirmation-content" style={{ width: 'min(500px,90vw)', textAlign: 'left' }} onClick={(e) => e.stopPropagation()}>
                <h3 style={{ marginTop: 0, borderBottom: '1px solid #eee', paddingBottom: 10 }}>
                  Bulk Edit ({selectedTasks.size} tasks)
                </h3>

                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, fontSize: 13 }}>

                  {/* 1. General Fields */}
                  <div style={{ gridColumn: '1 / -1', fontWeight: 600, color: '#475569', marginTop: 5 }}>General Details</div>

                  <div>
                    <label style={{ display: 'block', marginBottom: 4 }}>Status</label>
                    <select style={selectStyle} value={bulkDraft.status} onChange={e => setBulkDraft(d => ({ ...d, status: e.target.value }))}>
                      <option value="">(No Change)</option>
                      {DEFAULT_ENUMS.taskStatus.map(s => <option key={s} value={s}>{s}</option>)}
                    </select>
                  </div>

                  <div>
                    <label style={{ display: 'block', marginBottom: 4 }}>Department</label>
                    <select style={selectStyle} value={bulkDraft.department} onChange={e => setBulkDraft(d => ({ ...d, department: e.target.value }))}>
                      <option value="">(No Change)</option>
                      {enums.departments.map(s => <option key={s} value={s}>{s}</option>)}
                    </select>
                  </div>

                  <div>
                    <label style={{ display: 'block', marginBottom: 4 }}>Priority</label>
                    <select style={selectStyle} value={bulkDraft.priority} onChange={e => setBulkDraft(d => ({ ...d, priority: e.target.value }))}>
                      <option value="">(No Change)</option>
                      {DEFAULT_ENUMS.priority.map(s => <option key={s} value={s}>{s}</option>)}
                    </select>
                  </div>

                  {/* 2. Invoice Fields (Restricted) */}
                  {canManageInvoices() && (
                    <>
                      <div style={{ gridColumn: '1 / -1', fontWeight: 600, color: '#475569', marginTop: 10, paddingTop: 10, borderTop: '1px dashed #eee' }}>Invoicing</div>

                      <div style={{ gridColumn: '1 / -1', display: 'flex', gap: 15 }}>
                        <label><input type="checkbox" checked={bulkDraft.invoice_issued === true} onChange={(e) => setBulkDraft(d => ({ ...d, invoice_issued: e.target.checked ? true : null }))} /> Mark Issued</label>
                        <label><input type="checkbox" checked={bulkDraft.invoice_na === true} onChange={(e) => setBulkDraft(d => ({ ...d, invoice_na: e.target.checked ? true : null }))} /> Mark N/A</label>
                      </div>

                      <div style={{ gridColumn: '1 / -1' }}>
                        <label style={{ display: 'block', marginBottom: 4 }}>Invoice Status</label>
                        <select value={bulkDraft.invoice_status || ''} onChange={(e) => setBulkDraft(d => ({ ...d, invoice_status: e.target.value }))} style={selectStyle}>
                          <option value="">(No Change)</option>
                          <option value="Unpaid">Unpaid</option>
                          <option value="Paid">Paid</option>
                          <option value="Partially Paid">Partially Paid</option>
                        </select>
                      </div>
                    </>
                  )}
                </div>

                <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 20, paddingTop: 10, borderTop: '1px solid #eee' }}>
                  <button type="button" onClick={() => setShowBulkEdit(false)} style={btnSmall}>Cancel</button>
                  <button type="button" onClick={() => {
                    // --- APPLY LOGIC ---
                    const ids = Array.from(selectedTasks);
                    ids.forEach(id => {
                      const t = state.tasks.find(x => x.id === id);
                      if (!t) return;
                      const upd = { ...t };

                      // General Updates
                      if (bulkDraft.status) {
                        upd.status = bulkDraft.status;
                        if (bulkDraft.status === 'Completed' && !t.completion_date) upd.completion_date = todayISO();
                        if (bulkDraft.status !== 'Completed') upd.completion_date = null;
                      }
                      if (bulkDraft.department) upd.department = bulkDraft.department;
                      if (bulkDraft.priority) upd.priority = bulkDraft.priority;

                      // Invoice Updates
                      if (bulkDraft.invoice_issued === true) { upd.invoice_issued = true; upd.invoice_issued_date = upd.invoice_issued_date || todayISO(); }
                      if (bulkDraft.invoice_na === true) { upd.invoice_na = true; upd.invoice_issued = false; upd.invoice_status = 'N/A'; upd.invoice_issued_date = null; }
                      if (bulkDraft.invoice_status) {
                        upd.invoice_status = bulkDraft.invoice_status;
                        if (bulkDraft.invoice_status === 'Paid') upd.invoice_paid_date = upd.invoice_paid_date || todayISO();
                      }

                      upsertTask(upd);
                    });

                    setSelectedTasks(new Set()); // Clear selection
                    setBulkDraft({ status: '', department: '', priority: '', invoice_issued: null, invoice_na: null, invoice_status: '' }); // Reset form
                    setShowBulkEdit(false);
                  }} style={btnPrimarySmall}>Apply Changes</button>
                </div>
              </div>
            </div>
          )}

          {/* --- NEW BULK DELETE MODAL --- */}
          {showBulkDelete && (
            <div className="confirmation-modal">
              <div className="confirmation-content">
                <h3>⚠️ Confirm Bulk Delete</h3>
                <p>Are you sure you want to delete <b>{selectedTasks.size}</b> tasks?</p>
                <p style={{ fontSize: 12, color: '#dc2626' }}>This action cannot be undone.</p>

                <div style={{ display: 'flex', gap: '10px', justifyContent: 'center', marginTop: '15px' }}>
                  <button onClick={() => setShowBulkDelete(false)} style={btnSmall}>Cancel</button>
                  <button onClick={() => {
                    // --- DELETE LOGIC ---
                    setState(s => ({
                      ...s,
                      tasks: s.tasks.filter(t => !selectedTasks.has(t.id))
                    }));
                    setSelectedTasks(new Set());
                    setShowBulkDelete(false);
                  }} style={btnDangerSmall}>Yes, Delete All</button>
                </div>
              </div>
            </div>
          )}

          {/* Delete Confirmation Modal (Single Item) */}
          {/* Reminders Modal */}
          {selectedTaskForReminders && (
            <RemindersModal
              task={selectedTaskForReminders}
              subtask={selectedSubtaskForReminders}
              subtaskIndex={selectedSubtaskIndex}
              onClose={() => {
                setSelectedTaskForReminders(null);
                setSelectedSubtaskForReminders(null);
                setSelectedSubtaskIndex(null);
              }}
              onSave={(updatedReminders, subtask, subtaskIndex) => {
                if (subtask) {
                  // Update subtask reminders
                  const updatedSubtasks = selectedTaskForReminders.subtasks.map((s, idx) =>
                    idx === subtaskIndex ? { ...s, reminders: updatedReminders } : s
                  );
                  upsertTask({ ...selectedTaskForReminders, subtasks: updatedSubtasks });
                } else {
                  // Update main task reminders
                  upsertTask({ ...selectedTaskForReminders, reminders: updatedReminders });
                }
              }}
              clientsById={clientsById}
              currentUser={currentUser}
              fmtDDMMYY={fmtDDMMYY}
              uid={uid}
            />
          )}
          {taskToDelete && (
            <div className="confirmation-modal">
              <div className="confirmation-content">
                <h3>Confirm Delete</h3>
                <p>Are you sure you want to delete this task?</p>
                <div style={{ display: 'flex', gap: '10px', justifyContent: 'center', marginTop: '15px' }}>
                  <button onClick={cancelDelete} style={btnSmall}>Cancel</button>
                  <button onClick={confirmDelete} style={btnDangerSmall}>Delete</button>
                </div>
              </div>
            </div>
          )}

          {/* Task Editor */}
          {showEditor && editing && (
            <Modal z={150}
              onClose={() => setShowEditor(false)}
              title={editing?.id ? "Edit Task" : "New Task"}
              right={
                <>
                  <button
                    type="button"
                    onClick={() => {
                      saveEdit();
                      setTimeout(() => {
                        openNew();
                      }, 100);
                    }}
                    style={{ ...btnPrimarySmall, opacity: canEditTask(editing) ? 1 : 0.5, cursor: canEditTask(editing) ? "pointer" : "not-allowed" }}
                    disabled={!canEditTask(editing)}
                  >
                    Save & New
                  </button>
                  <button
                    type="button"
                    onClick={saveEdit}
                    style={{ ...btnPrimarySmall, opacity: canEditTask(editing) ? 1 : 0.5, cursor: canEditTask(editing) ? "pointer" : "not-allowed" }}
                    disabled={!canEditTask(editing)}
                  >
                    Save
                  </button>
                </>
              }
            >
              <div style={{ display: "grid", gridTemplateColumns: "minmax(0,1fr) minmax(0,1fr)", gap: 10, alignItems: "start" }}>
                {/* Client */}
                <Field label="Client">
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                    {/* Removed search box for filtering clients */}
                    <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
                      <select
                        value={editing.client_id}
                        onChange={(e) => {
                          const val = e.target.value;
                          setEditing((v) => ({ ...v, client_id: val }));
                          if (clientEditMode) setClientEditMode(false);
                        }}
                        style={selectStyle}
                      >
                        <option value="">Select a client</option>
                        {/* Option to add new client at the top */}
                        <option value="__new__">+ Add new client…</option>
                        {state.clients
                          .filter((c) => c.name.toLowerCase().includes(clientSearchTerm.toLowerCase()))
                          .sort((a, b) => a.name.localeCompare(b.name))
                          .map((c) => (
                            <option key={c.id} value={c.id}>
                              {c.name}
                            </option>
                          ))}
                      </select>
                      {editing.client_id && editing.client_id !== '__new__' && (
                        <>
                          <button
                            type="button"
                            title="Delete client (no tasks linked)"
                            disabled={state.tasks.some((t) => t.client_id === editing.client_id)}
                            style={state.tasks.some((t) => t.client_id === editing.client_id) ? btnDisabled : btnDanger}
                            onClick={() => {
                              const id = editing.client_id;
                              const nextId = state.clients.find((c) => c.id !== id)?.id || '';
                              setState((s) => ({ ...s, clients: s.clients.filter((c) => c.id !== id) }));
                              setEditing((v) => ({ ...v, client_id: nextId }));
                              setClientEditMode(false);
                            }}
                          >
                            Delete
                          </button>
                          <button
                            type="button"
                            style={btnSmall}
                            onClick={() => {
                              setClientEditMode(true);
                              const cur = state.clients.find((c) => c.id === editing.client_id);
                              setEditingClientNameInput(cur ? cur.name : '');
                            }}
                          >
                            Edit
                          </button>
                        </>
                      )}
                    </div>
                  </div>
                  {/* New client creation */}
                  {editing.client_id === '__new__' && (
                    <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
                      <input
                        value={newClientName}
                        onChange={(e) => setNewClientName(e.target.value)}
                        placeholder="Client name"
                        style={inputStyle}
                      />
                      <button
                        type="button"
                        onClick={() => {
                          const name = newClientName.trim();
                          if (!name) {
                            alert('Enter client name');
                            return;
                          }
                          const id = uid();
                          setState((s) => ({ ...s, clients: [{ id, name }, ...s.clients] }));
                          setEditing((v) => ({ ...v, client_id: id }));
                          setNewClientName('');
                          setClientEditMode(false);
                        }}
                        style={btnPrimary}
                      >
                        Add
                      </button>
                    </div>
                  )}
                  {/* Rename client UI */}
                  {editing.client_id && editing.client_id !== '__new__' && clientEditMode && (
                    <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
                      <input
                        value={editingClientNameInput}
                        onChange={(e) => setEditingClientNameInput(e.target.value)}
                        placeholder="New client name"
                        style={inputStyle}
                      />
                      <button
                        type="button"
                        style={btnPrimary}
                        onClick={() => {
                          const newName = editingClientNameInput.trim();
                          if (!newName) {
                            alert('Enter client name');
                            return;
                          }
                          setState((s) => ({
                            ...s,
                            clients: s.clients.map((c) =>
                              c.id === editing.client_id ? { ...c, name: newName } : c
                            ),
                          }));
                          setClientEditMode(false);
                        }}
                      >
                        Save
                      </button>
                      <button
                        type="button"
                        style={btnSmall}
                        onClick={() => {
                          setClientEditMode(false);
                        }}
                      >
                        Cancel
                      </button>
                    </div>
                  )}
                </Field>

                {/* Department with inline Add option */}
                <Field label="Department">
                  <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
                    <select
                      value={editing.department}
                      onChange={(e) => {
                        const val = e.target.value;
                        setEditing((v) => ({ ...v, department: val }));
                        // Close rename mode when switching
                        if (deptEditMode) setDeptEditMode(false);
                      }}
                      style={selectStyle}
                      disabled={!canViewAllDepartments()}
                    >
                      {/* Place the add-new option at the top so it's visible without scrolling */}
                      <option value="__new__">+ Add new department…</option>
                      {enums.departments.map((d) => (
                        <option key={d} value={d}>
                          {d}
                        </option>
                      ))}
                    </select>
                    {canViewAllDepartments() && editing.department && editing.department !== '__new__' && (
                      <>
                        <button
                          type="button"
                          style={btnDanger}
                          onClick={() => deleteDepartment(editing.department)}
                        >
                          Delete
                        </button>
                        <button
                          type="button"
                          style={btnSmall}
                          onClick={() => {
                            setDeptEditMode(true);
                            setEditingDeptNameInput(editing.department);
                          }}
                        >
                          Edit
                        </button>
                      </>
                    )}
                  </div>
                  {editing.department === '__new__' && (
                    <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
                      <input
                        value={newDeptName}
                        onChange={(e) => setNewDeptName(e.target.value)}
                        placeholder="Department name"
                        style={inputStyle}
                      />
                      <button
                        type="button"
                        onClick={() => {
                          addNewDepartment();
                          setDeptEditMode(false);
                        }}
                        style={btnPrimary}
                      >
                        Add
                      </button>
                    </div>
                  )}
                  {editing.department && editing.department !== '__new__' && deptEditMode && (
                    <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
                      <input
                        value={editingDeptNameInput}
                        onChange={(e) => setEditingDeptNameInput(e.target.value)}
                        placeholder="New department name"
                        style={inputStyle}
                      />
                      <button
                        type="button"
                        style={btnPrimary}
                        onClick={() => {
                          const oldName = editing.department;
                          const newName = editingDeptNameInput.trim();
                          if (!newName) {
                            alert('Enter department name');
                            return;
                          }
                          if (enums.departments.includes(newName)) {
                            alert('Department already exists');
                            return;
                          }
                          setEnums((e) => ({
                            ...e,
                            departments: e.departments.map((d) => (d === oldName ? newName : d)),
                          }));
                          setState((s) => ({
                            ...s,
                            tasks: s.tasks.map((t) =>
                              t.department === oldName ? { ...t, department: newName } : t
                            ),
                            users: s.users.map((u) =>
                              u.department === oldName ? { ...u, department: newName } : u
                            ),
                          }));
                          setEditing((v) => ({ ...v, department: newName }));
                          setDeptEditMode(false);
                        }}
                      >
                        Save
                      </button>
                      <button
                        type="button"
                        style={btnSmall}
                        onClick={() => {
                          setDeptEditMode(false);
                        }}
                      >
                        Cancel
                      </button>
                    </div>
                  )}
                </Field>

                {/* Assignee - Now works like Department/Client */}
                <Field label="Assignee">
                  <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
                    <select
                      value={editing.assignee || ""}
                      onChange={(e) => {
                        const val = e.target.value;
                        if (val === "__new__") {
                          // Show input for new assignee
                          setNewAssigneeMode(true);
                          setNewAssigneeName("");
                        } else {
                          setEditing(v => ({ ...v, assignee: val }));
                          setNewAssigneeMode(false);
                        }
                      }}
                      style={selectStyle}
                    >
                      <option value="">Select an assignee</option>
                      <option value="__new__">+ Add new assignee…</option>
                      {enums.assignees.map(a => (
                        <option key={a} value={a}>{a}</option>
                      ))}
                    </select>
                    {editing.assignee && editing.assignee !== "__new__" && (
                      <>
                        <button
                          type="button"
                          title="Delete assignee (not used in tasks)"
                          disabled={state.tasks.some(t => t.assignee === editing.assignee) || state.tasks.some(t => t.subtasks?.some(s => s.assignee === editing.assignee))}
                          style={state.tasks.some(t => t.assignee === editing.assignee) || state.tasks.some(t => t.subtasks?.some(s => s.assignee === editing.assignee)) ? btnDisabled : btnDanger}
                          onClick={() => {
                            const name = editing.assignee;
                            const nextList = enums.assignees.filter(x => x !== name);
                            setEnums(e => ({ ...e, assignees: nextList }));
                            setEditing(v => ({ ...v, assignee: "" }));
                            setAssigneeEditMode(false);
                          }}
                        >
                          Delete
                        </button>
                        <button
                          type="button"
                          style={btnSmall}
                          onClick={() => {
                            setAssigneeEditMode(true);
                            setEditingAssigneeName(editing.assignee);
                          }}
                        >
                          Edit
                        </button>
                      </>
                    )}
                  </div>

                  {/* New assignee creation */}
                  {newAssigneeMode && (
                    <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
                      <input
                        value={newAssigneeName}
                        onChange={(e) => setNewAssigneeName(e.target.value)}
                        placeholder="Assignee name"
                        style={inputStyle}
                      />
                      <button
                        type="button"
                        onClick={() => {
                          const name = newAssigneeName.trim();
                          if (!name) {
                            alert('Enter assignee name');
                            return;
                          }
                          if (enums.assignees.includes(name)) {
                            alert("Assignee already exists");
                            return;
                          }
                          setEnums(e => ({ ...e, assignees: [...e.assignees, name] }));
                          setEditing(v => ({ ...v, assignee: name }));
                          setNewAssigneeName("");
                          setNewAssigneeMode(false);
                        }}
                        style={btnPrimary}
                      >
                        Add
                      </button>
                      <button
                        type="button"
                        onClick={() => {
                          setNewAssigneeMode(false);
                          setEditing(v => ({ ...v, assignee: "" }));
                        }}
                        style={btnSmall}
                      >
                        Cancel
                      </button>
                    </div>
                  )}

                  {/* Rename assignee UI - ONLY ONE SECTION */}
                  {editing.assignee && editing.assignee !== "__new__" && assigneeEditMode && (
                    <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
                      <input
                        value={editingAssigneeName}
                        onChange={(e) => setEditingAssigneeName(e.target.value)}
                        placeholder="New assignee name"
                        style={inputStyle}
                      />
                      <button
                        type="button"
                        style={btnPrimary}
                        onClick={() => {
                          const oldName = editing.assignee;
                          const newName = editingAssigneeName.trim();
                          if (!newName) {
                            alert('Enter assignee name');
                            return;
                          }
                          if (enums.assignees.includes(newName) && newName !== oldName) {
                            alert("Assignee already exists");
                            return;
                          }
                          // Update in enums
                          setEnums(e => ({
                            ...e,
                            assignees: e.assignees.map(a => a === oldName ? newName : a)
                          }));
                          // Update in current task
                          setEditing(v => ({ ...v, assignee: newName }));
                          // Update in all tasks that use this assignee
                          setState(s => ({
                            ...s,
                            tasks: s.tasks.map(t => t.assignee === oldName ? { ...t, assignee: newName } : t),
                            // Also update in subtasks
                            tasks: s.tasks.map(t => ({
                              ...t,
                              subtasks: t.subtasks?.map(s => s.assignee === oldName ? { ...s, assignee: newName } : s)
                            }))
                          }));
                          setAssigneeEditMode(false);
                        }}
                      >
                        Save
                      </button>
                      <button
                        type="button"
                        style={btnSmall}
                        onClick={() => {
                          setAssigneeEditMode(false);
                        }}
                      >
                        Cancel
                      </button>
                    </div>
                  )}
                </Field>  {/* ONLY ONE CLOSING FIELD TAG HERE */}

                {/* Priority */}
                <Field label="Priority">
                  <select value={editing.priority} onChange={e => setEditing(v => ({ ...v, priority: e.target.value }))} style={selectStyle}>
                    {DEFAULT_ENUMS.priority.map(p => (
                      <option key={p} value={p}>{p}</option>
                    ))}
                  </select>
                </Field>

                {/* Recurrence */}
                <Field label="Recurrence">
                  <select value={editing.recurrence || "None"} onChange={e => setEditing(v => ({ ...v, recurrence: e.target.value }))} style={selectStyle}>
                    {DEFAULT_ENUMS.recurrencePatterns.map(p => (
                      <option key={p} value={p}>{p}</option>
                    ))}
                  </select>
                </Field>

                {/* Description */}
                <Field label="Task Description" full>
                  <textarea value={editing.task_description} onChange={e => setEditing(v => ({ ...v, task_description: e.target.value }))} style={{ ...inputStyle, height: 80, resize: "vertical" }} placeholder="Describe the task…" />
                </Field>

                {/* Start + Due + Status in the SAME ROW */}
                <Field label="Start Date (dd-mm-yy)">
                  <DateWithPicker dense valueISO={editing.start_date} onChangeISO={(iso) => setEditing(v => ({ ...v, start_date: iso }))} />
                </Field>
                <Field label="Due Date (dd-mm-yy)">
                  <DateWithPicker dense valueISO={editing.due_date} onChangeISO={(iso) => setEditing(v => ({ ...v, due_date: iso }))} />
                </Field>
                {/* Status is displayed but cannot be directly edited.  It will update based on checkboxes in the task list. */}
                <Field label="Status">
                  <div style={{ padding: '8px 10px', border: '1px solid #e2e8f0', borderRadius: 10, background: '#f8fafc', fontSize: 13 }}>
                    {(() => {
                      const isStarted = editing.status && editing.status !== 'Not Started';
                      const isCompleted = editing.status === 'Completed';
                      const isOverdue = editing.due_date && !isCompleted && (new Date(editing.due_date) < new Date());
                      if (isCompleted) return 'Completed';
                      if (isStarted) return isOverdue ? 'In Progress (Overdue)' : 'In Progress';
                      return 'Not Started';
                    })()}
                  </div>
                </Field>
                {/* If completed show the ability to adjust completion date */}
                {editing.status === "Completed" && (
                  <Field label="Completed (dd-mm-yy)">
                    <DateWithPicker dense valueISO={editing.completion_date || todayISO()} onChangeISO={(iso) => setEditing(v => ({ ...v, completion_date: iso }))} />
                  </Field>
                )}

                {/* Subtasks: Department + Start + Due - Fixed layout */}
                <Field label="Subtasks" full>
                  <div>
                    <div className="subtask-date-grid" style={{ display: "grid", gridTemplateColumns: "auto 1fr 140px 160px 120px 100px 100px auto", gap: 10, alignItems: "center" }}>
                      <div style={{ gridColumn: "1/-1", display: "grid", gridTemplateColumns: "subgrid", fontSize: 11, fontWeight: 600, color: '#475569', paddingBottom: 4 }}>
                        <div>Done</div>
                        <div>Title</div>
                        <div>Assignee</div>
                        <div>Client</div>
                        <div>Dept</div>
                        <div>Start</div>
                        <div>Due</div>
                        <div></div>
                      </div>
                      {(editing.subtasks || []).map((s, idx) => (
                        <div key={s.id || idx} style={{ display: 'contents' }}>
                          <input type="checkbox" checked={!!s.done} onChange={e => setEditing(v => {
                            const arr = [...(v.subtasks || [])]; arr[idx] = { ...arr[idx], done: e.target.checked }; return { ...v, subtasks: arr };
                          })} />
                          <input value={s.title} onChange={e => setEditing(v => {
                            const arr = [...(v.subtasks || [])]; arr[idx] = { ...arr[idx], title: e.target.value }; return { ...v, subtasks: arr };
                          })} placeholder="Subtask title" style={inputStyle} />

                          {/* Assignee for subtask */}
                          <select
                            value={s.assignee || ""}
                            onChange={e => setEditing(v => {
                              const arr = [...(v.subtasks || [])]; arr[idx] = { ...arr[idx], assignee: e.target.value }; return { ...v, subtasks: arr };
                            })}
                            style={selectStyle}
                          >
                            <option value="">— Assignee —</option>
                            {enums.assignees.map(a => <option key={a} value={a}>{a}</option>)}
                          </select>

                          <select value={s.client_id || editing.client_id || ""} onChange={e => setEditing(v => {
                            const arr = [...(v.subtasks || [])]; arr[idx] = { ...arr[idx], client_id: e.target.value }; return { ...v, subtasks: arr };
                          })} style={selectStyle}>
                            <option value="">— Client —</option>
                            {state.clients.slice().sort((a, b) => a.name.localeCompare(b.name)).map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
                          </select>
                          <select value={s.department || ""} onChange={e => setEditing(v => {
                            const arr = [...(v.subtasks || [])]; arr[idx] = { ...arr[idx], department: e.target.value }; return { ...v, subtasks: arr };
                          })} style={selectStyle}>
                            <option value="">— Department —</option>
                            {enums.departments.map(d => <option key={d}>{d}</option>)}
                          </select>
                          <DateWithPicker dense valueISO={s.start_date || ""} onChangeISO={(iso) => setEditing(v => {
                            const arr = [...(v.subtasks || [])]; arr[idx] = { ...arr[idx], start_date: iso }; return { ...v, subtasks: arr };
                          })} />
                          <DateWithPicker dense valueISO={s.due_date || ""} onChangeISO={(iso) => setEditing(v => {
                            const arr = [...(v.subtasks || [])]; arr[idx] = { ...arr[idx], due_date: iso }; return { ...v, subtasks: arr };
                          })} />
                          <button type="button" onClick={() => setEditing(v => {
                            const arr = [...(v.subtasks || [])]; arr.splice(idx, 1); return { ...v, subtasks: arr };
                          })} style={btnDangerLine}>Delete</button>
                        </div>
                      ))}
                    </div>
                    <div style={{ display: "flex", gap: 6, marginTop: 8 }}>
                      <button type="button"
                        onClick={() => {
                          setEditing(v => {
                            const subs = [...(v.subtasks || [])].sort((a, b) => {
                              const A = (a.title || "").trim().toLowerCase();
                              const B = (b.title || "").trim().toLowerCase();
                              if (!A && !B) return 0;
                              if (!A) return 1;
                              if (!B) return -1;
                              return A.localeCompare(B, "en", { numeric: true });
                            });
                            return { ...v, subtasks: subs };
                          });
                        }}
                        style={btnSmall}
                        title="Sort subtasks alphabetically (A→Z)">
                        🔤 Sort A→Z
                      </button>
                      <button type="button" onClick={() => setEditing(v => ({ ...v, subtasks: [...(v.subtasks || []), { id: uid(), title: "", department: "", start_date: "", due_date: "", done: false }] }))} style={btnSmall}>+ Add subtask</button>
                    </div>
                  </div>
                </Field>

                {/* Comments (chat) */}
                <Field label="Comments (chat)" full>
                  <div style={{ border: "1px solid #e2e8f0", borderRadius: 10, padding: 8, maxHeight: 220, overflow: "auto", background: "#f8fafc" }}>
                    {(editing.comments_thread || []).length === 0 && <div style={{ fontSize: 12, color: "#64748b" }}>No comments yet.</div>}
                    {(editing.comments_thread || []).map((c) => {
                      const who = usersById[c.user_id]?.name || (c.imported ? "Imported" : "Unknown");
                      const me = c.user_id === currentUserId ? " (you)" : "";
                      const when = new Date(c.ts).toLocaleString();
                      return (
                        <div key={c.id} style={{ marginBottom: 8 }}>
                          <div style={{ fontSize: 12, color: "#0f172a", fontWeight: 600 }}>{who}{me} <span style={{ color: "#64748b", fontWeight: 400 }}>· {when}</span></div>
                          <div style={{ fontSize: 13, background: "#fff", border: "1px solid #e2e8f0", borderRadius: 8, padding: "6px 8px" }}>{c.text}</div>
                        </div>
                      );
                    })}
                  </div>
                  <form onSubmit={(e) => {
                    e.preventDefault();
                    const text = newComment.trim(); if (!text) return;
                    const me = currentUserId;
                    addComment(editing.id, me, text);
                    setEditing(v => ({ ...v, comments_thread: [...(v.comments_thread || []), { id: uid(), user_id: me, text, ts: new Date().toISOString() }] }));
                    setNewComment("");
                  }} style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 6, marginTop: 6 }}>
                    <input value={newComment} onChange={e => setNewComment(e.target.value)} placeholder="Add a comment…" style={inputStyle} onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); e.currentTarget.form.requestSubmit(); } }} />
                    <button type="submit" style={btnPrimary}>Send</button>
                  </form>
                </Field>
              </div>

              <div style={{ display: "flex", gap: 6, justifyContent: "flex-end", marginTop: 10 }}>
                <button type="button" onClick={() => setShowEditor(false)} style={btnSmall}>Close</button>
                <button
                  type="button"
                  onClick={() => {
                    saveEdit();
                    setTimeout(() => {
                      openNew();
                    }, 100);
                  }}
                  style={{ ...btnPrimarySmall, opacity: canEditTask(editing) ? 1 : 0.5, cursor: canEditTask(editing) ? "pointer" : "not-allowed" }}
                  disabled={!canEditTask(editing)}
                >
                  Save & New
                </button>
                <button
                  type="button"
                  onClick={saveEdit}
                  style={{ ...btnPrimarySmall, opacity: canEditTask(editing) ? 1 : 0.5, cursor: canEditTask(editing) ? "pointer" : "not-allowed" }}
                  disabled={!canEditTask(editing)}
                >
                  Save
                </button>
              </div>
            </Modal>
          )}

          {/* Calendar Planner (owner/all vs dept-filtered) */}
          {showCalendar && (
            <Modal z={60}
              onClose={() => setShowCalendar(false)}
              title={`Planner · ${isOwner ? (calendarDeptFilter === 'All' ? 'All Departments' : calendarDeptFilter) : currentUser?.department || ''}`}
            >
              <div style={{ display: "flex", gap: 6, alignItems: "center", flexWrap: "wrap" }}>
                <button style={btnSmall} onClick={() => setCalendarAnchorDate(new Date())}>Today</button>
                <button
                  style={btnSmall}
                  onClick={() =>
                    setCalendarAnchorDate(d => {
                      const x = new Date(d); x.setDate(x.getDate() - stepByMode(calendarMode)); return x;
                    })
                  }
                >◀</button>
                <strong style={{ fontSize: 12 }}>
                  {calendarAnchorDate.toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric" })}
                </strong>
                <button
                  style={btnSmall}
                  onClick={() =>
                    setCalendarAnchorDate(d => {
                      const x = new Date(d); x.setDate(x.getDate() + stepByMode(calendarMode)); return x;
                    })
                  }
                >▶</button>

                <div style={{ marginLeft: "auto", display: "flex", gap: 6 }}>
                  <Toggle active={calendarMode === "day"} onClick={() => setCalendarMode("day")}>Day</Toggle>
                  <Toggle active={calendarMode === "week"} onClick={() => setCalendarMode("week")}>Week</Toggle>
                  <Toggle active={calendarMode === "month"} onClick={() => setCalendarMode("month")}>Month</Toggle>
                  <Toggle active={calendarMode === "year"} onClick={() => setCalendarMode("year")}>Year</Toggle>
                </div>
              </div>
              {/* Calendar filters */}
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8, alignItems: "center", marginTop: 8 }}>
                <span style={{ fontSize: 12, color: '#475569' }}>Show by:</span>
                <Toggle active={calendarBy === 'due'} onClick={() => setCalendarBy('due')}>Due Date</Toggle>
                <Toggle active={calendarBy === 'start'} onClick={() => setCalendarBy('start')}>Start Date</Toggle>

                {/* Department filter for CEO/Management */}
                {isOwner && (
                  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                    <span style={{ fontSize: 12, color: '#475569' }}>Dept:</span>
                    <select
                      value={calendarDeptFilter}
                      onChange={(e) => setCalendarDeptFilter(e.target.value)}
                      style={selectStyleXS}
                    >
                      <option value="All">All</option>
                      {enums.departments.map((d) => (
                        <option key={d}>{d}</option>
                      ))}
                    </select>
                  </div>
                )}

                {/* Assignee filter - available for everyone */}
                <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                  <span style={{ fontSize: 12, color: '#475569' }}>Assignee:</span>
                  <select
                    value={calendarAssigneeFilter}
                    onChange={(e) => setCalendarAssigneeFilter(e.target.value)}
                    style={selectStyleXS}
                  >
                    <option value="All">All</option>
                    {enums.assignees.map((a) => (
                      <option key={a}>{a}</option>
                    ))}
                  </select>
                </div>
              </div>

              <div style={{ marginTop: 10 }}>
                <CalendarView
                  tasks={filteredCalendarTasks}
                  clientsById={clientsById}
                  mode={calendarMode}
                  anchorDate={calendarAnchorDate}
                  by={calendarBy}
                  onOpenTask={(t) => { openEdit(t); }}
                  // When a month in year view is clicked, drill down to that month
                  onMonthClick={(month) => {
                    setCalendarAnchorDate(month);
                    setCalendarMode('month');
                  }}
                  // When a day cell in month view is clicked, drill down to that day
                  onDayClick={(date) => {
                    setCalendarAnchorDate(date);
                    setCalendarMode('day');
                  }}
                />
              </div>
            </Modal>
          )}

          {/* Reports Dashboard */}
          {showReport && (
            <Modal z={50} onClose={() => setShowReport(false)} title="Performance Analytics"
              right={
                <button
                  type="button"
                  onClick={() => setReportShowFinancials(!reportShowFinancials)}
                  style={{
                    background: reportShowFinancials ? '#3b82f6' : '#f1f5f9',
                    color: reportShowFinancials ? '#fff' : '#475569',
                    border: '1px solid #cbd5e1',
                    borderRadius: 6,
                    padding: '4px 8px',
                    fontSize: 11,
                    cursor: 'pointer',
                    display: 'flex',
                    alignItems: 'center',
                    gap: 4
                  }}
                  title={reportShowFinancials ? "Hide Financial Data" : "Show Financial Data"}
                >
                  {reportShowFinancials ? '👁️ Hide PKR' : '👁️ Show PKR'}
                </button>
              }
            >
              {/* Tabs for different views */}
              <div style={{ display: 'flex', gap: 4, marginBottom: 16, borderBottom: '1px solid #e2e8f0', paddingBottom: 8 }}>
                <button
                  type="button"
                  onClick={() => setReportView('department')}
                  style={{
                    background: reportView === 'department' ? '#3b82f6' : '#f1f5f9',
                    color: reportView === 'department' ? '#fff' : '#0f172a',
                    border: 'none',
                    borderRadius: 6,
                    padding: '6px 12px',
                    fontSize: 12,
                    cursor: 'pointer',
                    fontWeight: reportView === 'department' ? 600 : 400
                  }}
                >
                  Department Progress
                </button>
                <button
                  type="button"
                  onClick={() => setReportView('assignee')}
                  style={{
                    background: reportView === 'assignee' ? '#3b82f6' : '#f1f5f9',
                    color: reportView === 'assignee' ? '#fff' : '#0f172a',
                    border: 'none',
                    borderRadius: 6,
                    padding: '6px 12px',
                    fontSize: 12,
                    cursor: 'pointer',
                    fontWeight: reportView === 'assignee' ? 600 : 400
                  }}
                >
                  Assignee Performance
                </button>
                <button
                  type="button"
                  onClick={() => setReportView('overall')}
                  style={{
                    background: reportView === 'overall' ? '#3b82f6' : '#f1f5f9',
                    color: reportView === 'overall' ? '#fff' : '#0f172a',
                    border: 'none',
                    borderRadius: 6,
                    padding: '6px 12px',
                    fontSize: 12,
                    cursor: 'pointer',
                    fontWeight: reportView === 'overall' ? 600 : 400
                  }}
                >
                  Overall KPIs
                </button>
              </div>

              {/* Filters for Reports - Status, Department, Assignee */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12, flexWrap: 'wrap' }}>
                {/* Status Filter - Available for all report views */}
                <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                  <span style={{ fontSize: 12, color: '#475569' }}>Status:</span>
                  <select
                    value={reportStatusFilter}
                    onChange={(e) => setReportStatusFilter(e.target.value)}
                    style={selectStyleXS}
                  >
                    <option value="All">All Tasks</option>
                    <option value="Completed">Completed Only</option>
                    <option value="Pending">Pending Only</option>
                    <option value="Overdue">Overdue Only</option>
                    <option value="In Progress">In Progress Only</option>
                  </select>
                </div>

                {/* Department filter - only for Management/Owner */}
                {isOwner && reportView !== 'overall' && (
                  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                    <span style={{ fontSize: 12, color: '#475569' }}>Department:</span>
                    <select
                      value={reportDeptFilter}
                      onChange={(e) => setReportDeptFilter(e.target.value)}
                      style={selectStyleXS}
                    >
                      <option value="All">All</option>
                      {enums.departments.map((d) => (
                        <option key={d}>{d}</option>
                      ))}
                    </select>
                  </div>
                )}

                {/* Assignee filter - For assignee performance view */}
                {reportView === 'assignee' && (
                  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                    <span style={{ fontSize: 12, color: '#475569' }}>Assignee:</span>
                    <select
                      value={reportAssigneeFilter}
                      onChange={(e) => setReportAssigneeFilter(e.target.value)}
                      style={selectStyleXS}
                    >
                      <option value="All">All</option>
                      {(() => {
                        const assignees = Array.from(new Set(state.tasks.map(t => t.assignee).filter(Boolean))).sort();
                        return assignees.map(a => <option key={a} value={a}>{a}</option>);
                      })()}
                    </select>
                  </div>
                )}

                {/* Period filter - For assignee performance view */}
                {reportView === 'assignee' && (
                  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                    <span style={{ fontSize: 12, color: '#475569' }}>Period:</span>
                    <select
                      value={reportPeriod}
                      onChange={(e) => setReportPeriod(e.target.value)}
                      style={selectStyleXS}
                    >
                      <option value="all">All Time</option>
                      <option value="this_month">This Month</option>
                      <option value="last_month">Last Month</option>
                      <option value="this_quarter">This Quarter</option>
                      <option value="last_quarter">Last Quarter</option>
                      <option value="this_year">This Year</option>
                    </select>
                  </div>
                )}
              </div>

              {/* Content based on selected view */}
              {(() => {
                // Shared filtering logic for consistent reports
                const filteredReportTasks = enriched.filter(t => {
                  // Permission filter
                  if (!isOwner && currentUser?.department) {
                    const belongs = t.department === currentUser.department || (t.subtasks || []).some(s => s.department === currentUser.department);
                    if (!belongs) return false;
                  }

                  // Department filter
                  if (reportDeptFilter !== "All") {
                    const match = t.department === reportDeptFilter || (t.subtasks || []).some(s => s.department === reportDeptFilter);
                    if (!match) return false;
                  }

                  // Status filter
                  if (reportStatusFilter !== 'All') {
                    if (reportStatusFilter === 'Completed' && t.status !== 'Completed') return false;
                    if (reportStatusFilter === 'Pending' && (t.status === 'Completed' || t.status === 'Cancelled')) return false;
                    if (reportStatusFilter === 'Overdue' && !t.is_overdue) return false;
                    if (reportStatusFilter === 'In Progress' && t.status !== 'In Progress') return false;
                  }

                  // Note: period filter is handled inside AssigneePerformanceView currently
                  // but for Overall KPIs, we might want to apply it if view is 'overall'
                  return true;
                });

                switch (reportView) {
                  case 'assignee':
                    return <AssigneePerformanceView
                      tasks={filteredReportTasks}
                      reportDeptFilter={reportDeptFilter}
                      period={reportPeriod}
                      selectedAssignee={reportAssigneeFilter}
                      clientsById={clientsById}
                      onOpenTask={openEdit}
                      reportStatusFilter={reportStatusFilter}
                      isOwner={isOwner}
                      currentUser={currentUser}
                      selectedAssigneeDetails={selectedAssigneeDetails}
                      setSelectedAssigneeDetails={setSelectedAssigneeDetails}
                      modalStatusFilter={modalStatusFilter}
                      setModalStatusFilter={setModalStatusFilter}
                      showFinancials={reportShowFinancials}
                      setShowFinancials={setReportShowFinancials}
                    />;
                  case 'overall':
                    return <OverallKPIsView tasks={filteredReportTasks} />;
                  case 'department':
                    return <DepartmentProgressView
                      tasks={filteredReportTasks}
                      departmentFilter={reportDeptFilter}
                      isOwner={isOwner}
                      currentUser={currentUser}
                      clientsById={clientsById}
                      reportStatusFilter={reportStatusFilter}
                    />;
                }
              })()}
            </Modal>
          )}
          {/* Bulk Import (dd-mm-yy + compact calendar popovers + 6 rows) */}
          {showImport && (
            <Modal z={120} onClose={() => setShowImport(false)} title="Bulk Import Tasks (Paste from Excel/Sheets)">
              <p style={{ fontSize: 12, color: "#475569", marginTop: 0, marginBottom: 6 }}>
                Dates accepted as <b>dd-mm-yy</b> (or dd-mm-yyyy). Required: Department, Status, Invoice Status.
              </p>
              <div style={{ overflow: "auto", border: "1px solid #e2e8f0", borderRadius: 10 }}>
                <table style={{ width: "100%", fontSize: 12, minWidth: 980, borderCollapse: "collapse" }}>
                  <thead style={{ background: "#f1f5f9" }}>
                    <tr>
                      {["Client", "Department", "Task Description", "Start (dd-mm-yy)", "Due (dd-mm-yy)", "Status", "Invoice Status", "Row"].map(h =>
                        <th key={h} style={{ ...thSlim, padding: "6px" }}>{h}</th>
                      )}
                    </tr>
                  </thead>
                  <tbody>
                    {importRows.map((r, idx) => (
                      <tr key={idx} style={{ borderTop: "1px solid #e2e8f0" }}>
                        <td style={tdSlim}>
                          {/* Client selection: show a dropdown of existing clients plus an option to add new. When
                          the row's client value is set to '__input__' we show an input box and Add button. */}
                          {r.client === '__input__' ? (
                            <div style={{ display: 'flex', gap: 4 }}>
                              <input
                                value={importNewClients[idx] || ''}
                                onChange={(e) => {
                                  const val = e.target.value;
                                  setImportNewClients((prev) => ({ ...prev, [idx]: val }));
                                }}
                                placeholder="Client name"
                                style={{ ...inputStyle, fontSize: 12, padding: '4px 6px' }}
                              />
                              <button
                                type="button"
                                style={btnPrimarySmall}
                                onClick={() => {
                                  const name = (importNewClients[idx] || '').trim();
                                  if (!name) {
                                    alert('Enter client name');
                                    return;
                                  }
                                  const id = uid();
                                  // Add the new client to the beginning of the list
                                  setState((s) => ({ ...s, clients: [{ id, name }, ...s.clients] }));
                                  // Update row to use the name (not '__input__')
                                  updateImport(idx, 'client', name);
                                  // Clear typed value for this row
                                  setImportNewClients((prev) => {
                                    const copy = { ...prev };
                                    delete copy[idx];
                                    return copy;
                                  });
                                }}
                              >
                                Add
                              </button>
                              <button
                                type="button"
                                style={btnSmall}
                                onClick={() => {
                                  // Cancel input mode and reset the client field
                                  updateImport(idx, 'client', '');
                                  setImportNewClients((prev) => {
                                    const copy = { ...prev };
                                    delete copy[idx];
                                    return copy;
                                  });
                                }}
                              >
                                Cancel
                              </button>
                            </div>
                          ) : (
                            <select
                              value={r.client}
                              onChange={(e) => {
                                const val = e.target.value;
                                if (val === '__new__') {
                                  // Switch to input mode
                                  updateImport(idx, 'client', '__input__');
                                } else {
                                  updateImport(idx, 'client', val);
                                }
                              }}
                              onPaste={(e) => handleImportPaste(idx, 'client', e)}
                              style={selectStyleXS}
                            >
                              <option value=""></option>
                              {/* Place the add-new option at the top so it's visible without scrolling */}
                              <option value="__new__">+ Add new client…</option>
                              {state.clients.slice().sort((a, b) => a.name.localeCompare(b.name)).map((c) => (
                                <option key={c.id} value={c.name}>
                                  {c.name}
                                </option>
                              ))}
                            </select>
                          )}
                        </td>
                        <td style={tdSlim}>
                          <select value={r.department} onChange={e => updateImport(idx, "department", e.target.value)} style={selectStyleXS}>
                            <option value=""></option>
                            {enums.departments.map(d => <option key={d}>{d}</option>)}
                          </select>
                        </td>
                        <td className="status-cell-row" style={tdSlim}>
                          <textarea
                            value={r.description}
                            onChange={(e) => updateImport(idx, 'description', e.target.value)}
                            style={{ ...inputStyle, height: '40px', fontSize: '12px' }}
                            placeholder="Paste description here"
                          />
                        </td>
                        <td style={tdSlim}>
                          <DateMini valueStr={r.start} onChangeStr={(s) => updateImport(idx, "start", s)} dense />
                        </td>
                        <td style={tdSlim}>
                          <DateMini valueStr={r.due} onChangeStr={(s) => updateImport(idx, "due", s)} dense />
                        </td>
                        <td style={tdSlim}>
                          <select value={r.status} onChange={e => updateImport(idx, "status", e.target.value)} style={selectStyleXS}>
                            <option value=""></option>
                            {DEFAULT_ENUMS.taskStatus.map(s => <option key={s}>{s}</option>)}
                          </select>
                        </td>
                        <td className="status-cell-row" style={tdSlim}>
                          <select value={r.invoice} onChange={e => updateImport(idx, "invoice", e.target.value)} style={selectStyleXS}>
                            <option value=""></option>
                            {DEFAULT_ENUMS.invoiceStatus.map(s => <option key={s}>{s}</option>)}
                          </select>
                        </td>
                        <td style={{ ...tdSlim, textAlign: "right" }}>
                          <button type="button" onClick={() => removeImportRow(idx)} style={btnDangerLine}>Delete</button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>

              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 10 }}>
                <div style={{ display: "flex", gap: 6 }}>
                  <button type="button" onClick={addImportRow} style={btnSmall}>+ Add row</button>
                  <button type="button" onClick={() => setImportRows(Array.from({ length: 6 }, () => makeEmptyRow()))} style={btnSmall}>Clear</button>
                </div>
                <div style={{ display: "flex", gap: 6 }}>
                  <button type="button" onClick={() => setShowImport(false)} style={btnSmall}>Close</button>
                  <button type="button" onClick={doImport} style={btnPrimarySmall}>Import</button>
                </div>
              </div>
            </Modal>
          )}


          <footer style={{ marginTop: 12, textAlign: "center", fontSize: 10, color: "#64748b" }}>Bellwether Consulting ERP · CloudStorage · © 2025</footer>
        </div>
      );

      // Import grid helpers
      function updateImport(i, key, value) { setImportRows(rs => rs.map((r, idx) => idx === i ? { ...r, [key]: value } : r)); }
      function addImportRow() { setImportRows(r => [...r, makeEmptyRow()]); }
      function removeImportRow(i) { setImportRows(r => r.filter((_, idx) => idx !== i)); }
      function doImport() {
        try {
          const newClients = []; const imported = [];
          importRows.forEach(r => {
            // If the client field is in input mode ('__input__') or blank, skip this row.
            const clientName = (r.client === '__input__' ? '' : (r.client || '')).trim();
            if (!clientName) return;
            const department = (r.department || "").trim();
            const desc = (r.description || "").trim();
            const start_iso = parseDDMMYY((r.start || "").trim()) || ""; // dd-mm-yy
            const due_iso = parseDDMMYY((r.due || "").trim()) || "";
            const status = (r.status || "").trim();
            const invoice_status = (r.invoice || "").trim();
            if (!(enums.departments.includes(department) && DEFAULT_ENUMS.taskStatus.includes(status) && DEFAULT_ENUMS.invoiceStatus.includes(invoice_status))) return;
            let client = state.clients.find(c => c.name.toLowerCase() === clientName.toLowerCase());
            if (!client) { client = { id: uid(), name: clientName }; newClients.push(client); }
            imported.push({ id: uid(), client_id: client.id, department, task_description: desc, job_incharge_user_id: state.users.find(u => u.department === department)?.id || "", start_date: start_iso, due_date: due_iso, completion_date: status === "Completed" ? todayISO() : null, status, invoice_status, comments: "Imported", priority: "Medium", subtasks: [] });
          });
          if (imported.length === 0) throw new Error("No valid rows detected. Fill or paste data first.");
          setState(s => ({ ...s, clients: [...newClients, ...s.clients], tasks: [...imported, ...s.tasks] }));
          setShowImport(false); setImportRows(Array.from({ length: 6 }, () => makeEmptyRow()));
        } catch (e) { alert(e.message); }
      }
    }

    // Handle multi‑line/tab paste into the bulk import grid.  Starting from the given row
    // and column, populate successive rows and columns based on clipboard content.
    function handleImportPaste(startRow, colKey, event) {
      const keysOrder = ['client', 'department', 'description', 'start', 'due', 'status', 'invoice'];
      event.preventDefault();
      const text = event.clipboardData.getData('text/plain');
      if (!text) return;
      // Split into rows, dropping any completely empty rows
      const lines = text.trim().split(/\r?\n/).filter(l => l.trim() !== "");
      // Ensure enough rows exist to paste all lines
      while (importRows.length < startRow + lines.length) {
        addImportRow();
      }
      lines.forEach((line, rowOffset) => {
        // Split by tab to support multi‑column paste. Also trim each value
        const values = line.split(/\t/).map(v => v.trim());
        const rowIndex = startRow + rowOffset;
        // If only one value, paste down the same column
        if (values.length === 1) {
          updateImport(rowIndex, colKey, values[0]);
        } else {
          values.forEach((val, colIdx) => {
            const key = keysOrder[colIdx];
            if (key) {
              updateImport(rowIndex, key, val);
            }
          });
        }
      });
    }

    /* ============================== Login Screen ================================ */
    function LoginScreen({ users, onLogin }) {
      const [u, setU] = useState("");
      const [p, setP] = useState("");
      const [error, setError] = useState("");

      const tryLogin = (e) => {
        if (e) e.preventDefault();            // <-- stops any page navigation/reload
        const match = CREDENTIALS.find(c => c.username === u && c.password === p);
        if (!match) { setError("Invalid credentials"); return; }

        let userId = "";
        if (match.matchBy === "name") {
          const found = users.find(x => x.name === match.value);
          userId = found?.id || "";
        }
        if (!userId) { setError("User not found in directory"); return; }
        onLogin(userId);
      };

      return (
        <div style={{ minHeight: "100vh", display: "grid", placeItems: "center", padding: 16 }}>
          <div style={{ background: "#fff", borderRadius: 14, boxShadow: "0 10px 30px rgba(0,0,0,0.08)", padding: 18, width: "100%", maxWidth: 380 }}>
            <h2 style={{ margin: "0 0 12px 0" }}>Bellwether ERP Login</h2>
            <form onSubmit={tryLogin} style={{ display: "grid", gap: 8 }}>
              <div>
                <label style={labelStyleSmall}>User ID</label>
                <input value={u} onChange={e => setU(e.target.value)} style={controlHeight} placeholder="e.g. ABC" />
              </div>
              <div>
                <label style={labelStyleSmall}>Password</label>
                <input type="password" value={p} onChange={e => setP(e.target.value)} style={controlHeight} placeholder="Password" />
              </div>
              {error && <div style={{ color: "#b91c1c", fontSize: 12 }}>{error}</div>}
              <button type="submit" style={btnPrimarySmall}>Sign in</button>
            </form>
          </div>
        </div>
      );
    }

    /* ============================== Calendar View =============================== */
    function CalendarView({ tasks, clientsById, mode, anchorDate, by, onOpenTask, onMonthClick, onDayClick }) {
      const dateKey = (t) => by === "start" ? t.start_date : t.due_date;

      if (mode === "day") {
        // Use local ISO (no timezone shift) for matching tasks
        const dayISO = toLocalISO(anchorDate);
        const list = tasks.filter(t => dateKey(t) === dayISO);
        return (
          <div style={cardLite}>
            <h4 style={{ margin: "0 0 6px 0" }}>Day · {fmtDDMMYY(dayISO)}</h4>
            {list.length === 0 ? <div style={{ fontSize: 12, color: "#64748b" }}>No tasks</div> :
              <ol style={{ margin: 0, paddingLeft: 20 }}>
                {list.map((t, index) => (
                  <li key={t.id} style={{ margin: "4px 0" }}>
                    <button
                      type="button"
                      onClick={() => onOpenTask(t)}
                      style={{ background: "none", border: "none", padding: 0, textAlign: "left", textDecoration: t.status === "Completed" ? "line-through" : "underline", opacity: t.status === "Completed" ? 0.5 : 1, cursor: "pointer", fontSize: "inherit" }}
                      title="Open task"
                    >
                      {clientsById[t.client_id]?.name || "—"} • {t.task_description}
                    </button>
                  </li>
                ))}
              </ol>}
          </div>
        );
      }

      if (mode === "week") {
        const start = startOfWeekPKT(anchorDate);
        const days = Array.from({ length: 7 }, (_, i) => { const d = new Date(start); d.setDate(d.getDate() + i); return d; });
        return (
          <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 6 }}>
            {days.map((d, i) => {
              const dayISO = toLocalISO(d);
              const list = tasks.filter(t => dateKey(t) === dayISO);
              return (
                <div key={i} style={cardLite}>
                  <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 4 }}>{d.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" })}</div>
                  {list.length === 0 ? <div style={{ fontSize: 11, color: "#64748b" }}>No tasks</div> :
                    <ol style={{ margin: 0, paddingLeft: 18, fontSize: 11 }}>
                      {list.map((t, idx) => (
                        <li key={t.id} style={{ margin: "2px 0" }}>
                          <button
                            type="button"
                            onClick={() => onOpenTask(t)}
                            style={{ background: "none", border: "none", padding: 0, textAlign: "left", textDecoration: t.status === "Completed" ? "line-through" : "underline", opacity: t.status === "Completed" ? 0.5 : 1, cursor: "pointer", fontSize: "inherit" }}
                            title="Open task"
                          >
                            {clientsById[t.client_id]?.name || "—"}
                          </button>
                        </li>
                      ))}
                    </ol>}
                </div>
              );
            })}
          </div>
        );
      }

      if (mode === "month") {
        const year = anchorDate.getFullYear(), month = anchorDate.getMonth();
        const first = new Date(year, month, 1);
        const last = new Date(year, month + 1, 0);
        const days = Array.from({ length: last.getDate() }, (_, i) => new Date(year, month, i + 1));
        const padStart = (first.getDay() + 6) % 7; // Mon=0, Sun=6
        const padEnd = 42 - (padStart + days.length); // 6 rows of 7 days

        return (
          <div>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 4, textAlign: "center", fontSize: 12, fontWeight: 600, marginBottom: 4 }}>
              {["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"].map(d => <div key={d}>{d}</div>)}
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 4 }}>
              {Array(padStart).fill(null).map((_, i) => <div key={`pad-${i}`} className="calendar-day"></div>)}
              {days.map((d, i) => {
                const dayISO = toLocalISO(d);
                const list = tasks.filter(t => dateKey(t) === dayISO);
                const isToday = dayISO === toLocalISO(new Date());
                return (
                  <div
                    key={i}
                    className="calendar-day"
                    style={{ background: isToday ? "#f0f9ff" : "#fff", cursor: "pointer" }}
                    onClick={() => onDayClick(d)}
                    title={`${fmtDDMMYY(dayISO)} • ${list.length} task(s)`}
                  >
                    <div style={{ fontSize: 12, fontWeight: isToday ? 700 : 400, color: isToday ? "#0369a1" : "inherit" }}>{d.getDate()}</div>
                    {list.length > 0 && (
                      <ol className="calendar-task-list">
                        {list.slice(0, 3).map((t, idx) => (
                          <li key={t.id} style={{ margin: "2px 0" }}>
                            <button
                              type="button"
                              onClick={(e) => { e.stopPropagation(); onOpenTask(t); }}
                              style={{ background: "none", border: "none", padding: 0, textAlign: "left", textDecoration: t.status === "Completed" ? "line-through" : "underline", opacity: t.status === "Completed" ? 0.5 : 1, cursor: "pointer", fontSize: "inherit" }}
                              title="Open task"
                            >
                              {clientsById[t.client_id]?.name || "—"}
                            </button>
                          </li>
                        ))}
                        {list.length > 3 && (
                          <li style={{ fontSize: 10, color: "#64748b" }}>+{list.length - 3} more</li>
                        )}
                      </ol>
                    )}
                  </div>
                );
              })}
              {Array(padEnd).fill(null).map((_, i) => <div key={`pad-end-${i}`} className="calendar-day"></div>)}
            </div>
          </div>
        );
      }

      if (mode === "year") {
        const year = anchorDate.getFullYear();
        const months = Array.from({ length: 12 }, (_, i) => new Date(year, i, 1));
        return (
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8 }}>
            {months.map((m, i) => {
              const monthTasks = tasks.filter(t => {
                const tDate = dateKey(t);
                if (!tDate) return false;
                const d = new Date(tDate + "T00:00:00");
                return d.getFullYear() === year && d.getMonth() === i;
              });
              return (
                <div
                  key={i}
                  style={{ ...cardLite, minHeight: 60, cursor: "pointer", textAlign: "center" }}
                  onClick={() => onMonthClick(m)}
                  title={m.toLocaleDateString(undefined, { month: "long", year: "numeric" })}
                >
                  <div style={{ fontSize: 12, fontWeight: 600 }}>{m.toLocaleDateString(undefined, { month: "short" })}</div>
                  <div style={{ fontSize: 11, marginTop: 2 }}>{monthTasks.length} task{monthTasks.length !== 1 ? "s" : ""}</div>
                </div>
              );
            })}
          </div>
        );
      }
    }
    /* ============================== Financial Performance View =============================== */
    function FinancialAnalysisView({ tasks, clientsById }) {
      // Calculate financial metrics by department
      const departmentFinancials = useMemo(() => {
        const deptMap = {};

        tasks.forEach(t => {
          const dept = t.department || 'Unknown';
          if (!deptMap[dept]) {
            deptMap[dept] = {
              name: dept,
              totalTasks: 0,
              completedTasks: 0,
              totalRevenue: 0,
              collectedRevenue: 0,
              pendingRevenue: 0,
              tasks: []
            };
          }

          const deptData = deptMap[dept];
          deptData.totalTasks++;
          deptData.tasks.push(t);

          // Task revenue
          const taskAmount = Number(t.invoice_amount) || 0;
          deptData.totalRevenue += taskAmount;

          if (t.invoice_status === 'Paid') {
            deptData.collectedRevenue += taskAmount;
          } else if (t.invoice_status === 'Unpaid' || t.invoice_status === 'Partially Paid') {
            deptData.pendingRevenue += taskAmount;
          }

          if (t.status === 'Completed') {
            deptData.completedTasks++;
          }
        });

        // Calculate by assignee within each department
        Object.values(deptMap).forEach(deptData => {
          const assigneeMap = {};

          deptData.tasks.forEach(t => {
            const assignee = t.assignee || 'Unassigned';
            if (!assigneeMap[assignee]) {
              assigneeMap[assignee] = {
                name: assignee,
                totalTasks: 0,
                completedTasks: 0,
                totalRevenue: 0,
                collectedRevenue: 0,
                pendingRevenue: 0
              };
            }

            const assigneeData = assigneeMap[assignee];
            assigneeData.totalTasks++;

            const taskAmount = Number(t.invoice_amount) || 0;
            assigneeData.totalRevenue += taskAmount;

            if (t.invoice_status === 'Paid') {
              assigneeData.collectedRevenue += taskAmount;
            } else if (t.invoice_status === 'Unpaid' || t.invoice_status === 'Partially Paid') {
              assigneeData.pendingRevenue += taskAmount;
            }

            if (t.status === 'Completed') {
              assigneeData.completedTasks++;
            }
          });

          deptData.assignees = Object.values(assigneeMap).sort((a, b) => b.totalRevenue - a.totalRevenue);
        });

        return Object.values(deptMap).sort((a, b) => b.totalRevenue - a.totalRevenue);
      }, [tasks]);

      // Calculate overall financial metrics
      const overallMetrics = useMemo(() => {
        let totalRevenue = 0;
        let collectedRevenue = 0;
        let pendingRevenue = 0;
        let totalTasks = tasks.length;
        let completedTasks = tasks.filter(t => t.status === 'Completed').length;

        tasks.forEach(t => {
          const taskAmount = Number(t.invoice_amount) || 0;
          totalRevenue += taskAmount;

          if (t.invoice_status === 'Paid') {
            collectedRevenue += taskAmount;
          } else if (t.invoice_status === 'Unpaid' || t.invoice_status === 'Partially Paid') {
            pendingRevenue += taskAmount;
          }
        });

        const collectionRate = totalRevenue > 0 ? Math.round((collectedRevenue / totalRevenue) * 100) : 0;
        const completionRate = totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0;
        const avgTaskValue = totalTasks > 0 ? Math.round(totalRevenue / totalTasks) : 0;

        return {
          totalRevenue,
          collectedRevenue,
          pendingRevenue,
          collectionRate,
          completionRate,
          avgTaskValue,
          totalTasks,
          completedTasks
        };
      }, [tasks]);

      return (
        <div style={{ maxHeight: '60vh', overflow: 'auto' }}>
          {/* Overall Financial KPIs */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 12, marginBottom: 20 }}>
            <div style={{ background: 'linear-gradient(135deg, #d1fae5, #a7f3d0)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#065f46' }}>PKR {overallMetrics.totalRevenue.toLocaleString()}</div>
              <div style={{ fontSize: 12, color: '#047857', fontWeight: 600 }}>Total Revenue</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #bbf7d0, #86efac)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#166534' }}>PKR {overallMetrics.collectedRevenue.toLocaleString()}</div>
              <div style={{ fontSize: 12, color: '#16a34a', fontWeight: 600 }}>Collected</div>
              <div style={{ fontSize: 11, color: '#475569', marginTop: 4 }}>{overallMetrics.collectionRate}% collection rate</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #fecaca, #f87171)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#991b1b' }}>PKR {overallMetrics.pendingRevenue.toLocaleString()}</div>
              <div style={{ fontSize: 12, color: '#dc2626', fontWeight: 600 }}>Pending</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #fde68a, #fcd34d)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#92400e' }}>PKR {overallMetrics.avgTaskValue.toLocaleString()}</div>
              <div style={{ fontSize: 12, color: '#d97706', fontWeight: 600 }}>Avg Task Value</div>
            </div>
          </div>

          {/* Department-wise Financial Analysis */}
          <h4 style={{ margin: '20px 0 12px 0', fontSize: 14, color: '#475569' }}>Department Performance</h4>
          <div style={{ border: '1px solid #e2e8f0', borderRadius: 8, overflow: 'hidden', marginBottom: 20 }}>
            <table style={{ width: '100%', fontSize: 12, borderCollapse: 'collapse' }}>
              <thead style={{ background: '#f1f5f9' }}>
                <tr>
                  <th style={{ padding: '10px', textAlign: 'left' }}>Department</th>
                  <th style={{ padding: '10px', textAlign: 'center' }}>Tasks</th>
                  <th style={{ padding: '10px', textAlign: 'center' }}>Completion</th>
                  <th style={{ padding: '10px', textAlign: 'right' }}>Total Revenue</th>
                  <th style={{ padding: '10px', textAlign: 'right' }}>Collected</th>
                  <th style={{ padding: '10px', textAlign: 'right' }}>Pending</th>
                  <th style={{ padding: '10px', textAlign: 'center' }}>Efficiency</th>
                </tr>
              </thead>
              <tbody>
                {departmentFinancials.map((dept, idx) => {
                  const completionRate = dept.totalTasks > 0 ? Math.round((dept.completedTasks / dept.totalTasks) * 100) : 0;
                  const collectionRate = dept.totalRevenue > 0 ? Math.round((dept.collectedRevenue / dept.totalRevenue) * 100) : 0;
                  const avgTaskValue = dept.totalTasks > 0 ? Math.round(dept.totalRevenue / dept.totalTasks) : 0;

                  return (
                    <tr key={dept.name} style={{ borderTop: '1px solid #e2e8f0', background: idx % 2 === 0 ? '#fff' : '#f8fafc' }}>
                      <td style={{ padding: '10px', fontWeight: 600 }}>{dept.name}</td>
                      <td style={{ padding: '10px', textAlign: 'center' }}>
                        <div>{dept.totalTasks}</div>
                        <div style={{ fontSize: 11, color: '#64748b' }}>{completionRate}% done</div>
                      </td>
                      <td style={{ padding: '10px', textAlign: 'center' }}>
                        <div>{dept.completedTasks}/{dept.totalTasks}</div>
                        <div style={{ fontSize: 11, color: '#64748b' }}>{completionRate}%</div>
                      </td>
                      <td style={{ padding: '10px', textAlign: 'right', fontWeight: 600 }}>
                        PKR {dept.totalRevenue.toLocaleString()}
                        <div style={{ fontSize: 11, color: '#64748b' }}>Avg: PKR {avgTaskValue.toLocaleString()}</div>
                      </td>
                      <td style={{ padding: '10px', textAlign: 'right', color: '#16a34a' }}>
                        PKR {dept.collectedRevenue.toLocaleString()}
                        <div style={{ fontSize: 11, color: '#64748b' }}>{collectionRate}%</div>
                      </td>
                      <td style={{ padding: '10px', textAlign: 'right', color: '#dc2626' }}>
                        PKR {dept.pendingRevenue.toLocaleString()}
                        <div style={{ fontSize: 11, color: '#64748b' }}>{100 - collectionRate}%</div>
                      </td>
                      <td style={{ padding: '10px', textAlign: 'center' }}>
                        <div style={{
                          background: completionRate >= 80 ? '#dcfce7' : completionRate >= 60 ? '#fef9c3' : '#fee2e2',
                          color: completionRate >= 80 ? '#166534' : completionRate >= 60 ? '#854d0e' : '#991b1b',
                          padding: '4px 8px',
                          borderRadius: 999,
                          fontSize: 11,
                          fontWeight: 600,
                          display: 'inline-block'
                        }}>
                          {completionRate >= 80 ? 'High' : completionRate >= 60 ? 'Medium' : 'Low'}
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>

          {/* Export button */}
          <div style={{ textAlign: 'right' }}>
            <button
              type="button"
              onClick={() => exportFinancialReport(departmentFinancials)}
              style={{ ...btnPrimarySmall, display: 'inline-flex', alignItems: 'center', gap: 6 }}
            >
              💰 Export Financial Report
            </button>
          </div>
        </div>
      );
    }
    const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042', '#8884d8', '#82ca9d'];
    // Export financial report
    const exportFinancialReport = (departmentFinancials) => {
      try {
        const header = [
          "Department",
          "Total Tasks",
          "Completed Tasks",
          "Completion Rate %",
          "Total Revenue (PKR)",
          "Collected Revenue (PKR)",
          "Pending Revenue (PKR)",
          "Collection Rate %",
          "Avg Task Value (PKR)",
          "Efficiency Rating"
        ];

        const rowsData = departmentFinancials.map(dept => {
          const completionRate = dept.totalTasks > 0 ? Math.round((dept.completedTasks / dept.totalTasks) * 100) : 0;
          const collectionRate = dept.totalRevenue > 0 ? Math.round((dept.collectedRevenue / dept.totalRevenue) * 100) : 0;
          const avgTaskValue = dept.totalTasks > 0 ? Math.round(dept.totalRevenue / dept.totalTasks) : 0;

          return [
            dept.name,
            dept.totalTasks,
            dept.completedTasks,
            completionRate,
            dept.totalRevenue,
            dept.collectedRevenue,
            dept.pendingRevenue,
            collectionRate,
            avgTaskValue,
            completionRate >= 80 ? 'High' : completionRate >= 60 ? 'Medium' : 'Low'
          ];
        });

        const csvContent = [header, ...rowsData].map(r => r.map(csvEscape).join(",")).join("\n");
        downloadFile(`financial_analysis_${todayISO()}.csv`, "\uFEFF" + csvContent, "text/csv;charset=utf-8");
      } catch (e) {
        console.error(e);
        alert("Export failed. Please try again.");
      }
    };

    /* ============================== Assignee Performance View =============================== */
    function AssigneePerformanceView({
      tasks, reportDeptFilter, period, selectedAssignee, clientsById, onOpenTask,
      reportStatusFilter, isOwner, currentUser,
      selectedAssigneeDetails, setSelectedAssigneeDetails,
      modalStatusFilter, setModalStatusFilter,
      showFinancials, setShowFinancials
    }) {
      // Add local ui state
      const [expandedAssigneeTasks, setExpandedAssigneeTasks] = useState({});

      // Filter tasks based on department, period, and assignee
      const filteredTasks = useMemo(() => {
        // First, apply user permission filter
        let baseTasks = tasks;

        if (!isOwner && currentUser?.department) {
          // Non-owners can only see tasks from their own department
          baseTasks = tasks.filter(t =>
            t.department === currentUser.department ||
            (t.subtasks || []).some(s => s.department === currentUser.department)
          );
        }

        let filtered = baseTasks.filter(t => {
          // Department filter
          if (reportDeptFilter !== "All" && t.department !== reportDeptFilter) {
            // Also check if any subtask belongs to this department
            const subtaskMatchesDept = t.subtasks && t.subtasks.some(s => s.department === reportDeptFilter);
            if (!subtaskMatchesDept) return false;
          }

          // Status filter
          if (reportStatusFilter !== 'All') {
            if (reportStatusFilter === 'Completed' && t.status !== 'Completed') return false;
            if (reportStatusFilter === 'Pending' && (t.status === 'Completed' || t.status === 'Cancelled')) return false;
            if (reportStatusFilter === 'Overdue' && !t.is_overdue) return false;
            if (reportStatusFilter === 'In Progress' && t.status !== 'In Progress') return false;
          }

          // Assignee filter
          if (selectedAssignee !== "All") {
            const matchesAssignee = t.assignee === selectedAssignee ||
              (t.subtasks && t.subtasks.some(s => s.assignee === selectedAssignee));
            if (!matchesAssignee) return false;
          }

          // Period filter
          if (period !== "all") {
            const now = new Date();
            let startDate, endDate;

            switch (period) {
              case 'this_month':
                startDate = new Date(now.getFullYear(), now.getMonth(), 1);
                endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0);
                break;
              case 'last_month':
                startDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
                endDate = new Date(now.getFullYear(), now.getMonth(), 0);
                break;
              case 'this_quarter':
                const quarter = Math.floor(now.getMonth() / 3);
                startDate = new Date(now.getFullYear(), quarter * 3, 1);
                endDate = new Date(now.getFullYear(), (quarter + 1) * 3, 0);
                break;
              case 'last_quarter':
                const lastQuarter = Math.floor((now.getMonth() - 3) / 3);
                startDate = new Date(now.getFullYear(), lastQuarter * 3, 1);
                endDate = new Date(now.getFullYear(), (lastQuarter + 1) * 3, 0);
                break;
              case 'this_year':
                startDate = new Date(now.getFullYear(), 0, 1);
                endDate = new Date(now.getFullYear(), 11, 31);
                break;
              default:
                return true;
            }

            // Check main task date
            let taskDate = t.start_date ? toDate(t.start_date) : null;
            if (!taskDate && t.subtasks && t.subtasks.length > 0) {
              // If no main task date, check subtask dates
              const subtaskWithDate = t.subtasks.find(s => s.start_date);
              taskDate = subtaskWithDate ? toDate(subtaskWithDate.start_date) : null;
            }

            if (!taskDate) return false;
            if (taskDate < startDate || taskDate > endDate) return false;
          }

          return true;
        });

        return filtered;
      }, [tasks, reportDeptFilter, period, selectedAssignee, reportStatusFilter, isOwner, currentUser]);

      // Calculate assignee statistics
      const assigneeStats = useMemo(() => {
        const stats = {};
        const assigneeFinancials = {};

        filteredTasks.forEach(task => {
          // Process main task
          const assignee = task.assignee || "Unassigned";
          const department = task.department || "Unknown";

          if (!stats[assignee]) {
            stats[assignee] = {
              name: assignee,
              department: department,
              totalTasks: 0,
              completedTasks: 0,
              onTimeTasks: 0,
              lateTasks: 0,
              pendingTasks: 0,
              overdueTasks: 0,
              totalCompletionTime: 0,
              highPriorityTasks: 0,
              completedTasksList: [],
              pendingTasksList: []
            };
            assigneeFinancials[assignee] = {
              totalRevenue: 0,
              collectedRevenue: 0,
              pendingRevenue: 0
            };
          }

          const stat = stats[assignee];
          const financial = assigneeFinancials[assignee];
          stat.totalTasks++;

          // Track high priority tasks
          if (task.priority === 'High' || task.priority === 'Critical') {
            stat.highPriorityTasks++;
          }

          // Track financials
          const taskAmount = Number(task.invoice_amount) || 0;
          financial.totalRevenue += taskAmount;
          if (task.invoice_status === 'Paid') {
            financial.collectedRevenue += taskAmount;
          } else if (task.invoice_status === 'Unpaid' || task.invoice_status === 'Partially Paid') {
            financial.pendingRevenue += taskAmount;
          }

          if (task.status === 'Completed') {
            stat.completedTasks++;
            stat.completedTasksList.push(task);

            // Check if completed on time
            if (task.completion_date && task.due_date) {
              const completionDate = toDate(task.completion_date);
              const dueDate = toDate(task.due_date);

              // Calculate completion time
              if (task.start_date) {
                const startDate = toDate(task.start_date);
                const completionTime = Math.round((completionDate - startDate) / (1000 * 60 * 60 * 24));
                stat.totalCompletionTime += completionTime;
              }

              if (completionDate <= dueDate) {
                stat.onTimeTasks++;
              } else {
                stat.lateTasks++;
              }
            }
          } else if (task.status === 'Cancelled') {
            // Don't count cancelled tasks in pending
          } else {
            stat.pendingTasks++;
            stat.pendingTasksList.push(task);

            // Check if overdue
            if (task.is_overdue) {
              stat.overdueTasks++;
            }
          }

          // Process subtasks
          if (task.subtasks && task.subtasks.length > 0) {
            task.subtasks.forEach(subtask => {
              const subAssignee = subtask.assignee || "Unassigned";

              if (!stats[subAssignee]) {
                stats[subAssignee] = {
                  name: subAssignee,
                  department: subtask.department || department,
                  totalTasks: 0,
                  completedTasks: 0,
                  onTimeTasks: 0,
                  lateTasks: 0,
                  pendingTasks: 0,
                  overdueTasks: 0,
                  totalCompletionTime: 0,
                  highPriorityTasks: 0,
                  completedTasksList: [],
                  pendingTasksList: []
                };
                assigneeFinancials[subAssignee] = {
                  totalRevenue: 0,
                  collectedRevenue: 0,
                  pendingRevenue: 0
                };
              }

              const subStat = stats[subAssignee];
              const subFinancial = assigneeFinancials[subAssignee];
              subStat.totalTasks++;

              // Track financials for subtasks
              const subAmount = Number(subtask.invoice_amount) || 0;
              subFinancial.totalRevenue += subAmount;
              if (subtask.invoice_status === 'Paid') {
                subFinancial.collectedRevenue += subAmount;
              } else if (subtask.invoice_status === 'Unpaid' || subtask.invoice_status === 'Partially Paid') {
                subFinancial.pendingRevenue += subAmount;
              }

              if (subtask.done || subtask.status === 'Completed') {
                subStat.completedTasks++;
                subStat.completedTasksList.push(subtask);
              } else {
                subStat.pendingTasks++;
                subStat.pendingTasksList.push(subtask);
              }
            });
          }
        });

        // Convert to array and calculate percentages
        return Object.values(stats).map(stat => {
          const financial = assigneeFinancials[stat.name] || { totalRevenue: 0, collectedRevenue: 0, pendingRevenue: 0 };
          return {
            ...stat,
            ...financial,
            completionRate: stat.totalTasks > 0 ? Math.round((stat.completedTasks / stat.totalTasks) * 100) : 0,
            onTimeRate: stat.completedTasks > 0 ? Math.round((stat.onTimeTasks / stat.completedTasks) * 100) : 0,
            overdueRate: stat.pendingTasks > 0 ? Math.round((stat.overdueTasks / stat.pendingTasks) * 100) : 0,
            avgCompletionTime: stat.completedTasks > 0 ? Math.round(stat.totalCompletionTime / stat.completedTasks) : 0,
            highPriorityRate: stat.totalTasks > 0 ? Math.round((stat.highPriorityTasks / stat.totalTasks) * 100) : 0,
            collectionRate: financial.totalRevenue > 0 ? Math.round((financial.collectedRevenue / financial.totalRevenue) * 100) : 0
          };
        }).sort((a, b) => b.completionRate - a.completionRate);
      }, [filteredTasks]);

      // Calculate overall statistics
      const overallStats = useMemo(() => {
        if (assigneeStats.length === 0) return null;

        const totalRevenue = assigneeStats.reduce((sum, stat) => sum + stat.totalRevenue, 0);
        const collectedRevenue = assigneeStats.reduce((sum, stat) => sum + stat.collectedRevenue, 0);

        return {
          totalAssignees: assigneeStats.length,
          avgCompletionRate: Math.round(assigneeStats.reduce((sum, stat) => sum + stat.completionRate, 0) / assigneeStats.length),
          avgOnTimeRate: Math.round(assigneeStats.reduce((sum, stat) => sum + stat.onTimeRate, 0) / assigneeStats.length),
          totalTasks: assigneeStats.reduce((sum, stat) => sum + stat.totalTasks, 0),
          totalCompleted: assigneeStats.reduce((sum, stat) => sum + stat.completedTasks, 0),
          totalPending: assigneeStats.reduce((sum, stat) => sum + stat.pendingTasks, 0),
          totalRevenue,
          collectedRevenue,
          collectionRate: totalRevenue > 0 ? Math.round((collectedRevenue / totalRevenue) * 100) : 0
        };
      }, [assigneeStats]);

      if (filteredTasks.length === 0) {
        return <div style={{ textAlign: 'center', padding: '20px', color: '#64748b' }}>No tasks found for the selected filters.</div>;
      }

      return (
        <div>  {/* Wrap everything in a single parent div */}
          <div style={{ maxHeight: '60vh', overflow: 'auto' }}>

            {/* Overall KPIs */}
            {overallStats && (
              <div style={{ display: 'grid', gridTemplateColumns: `repeat(${showFinancials ? 4 : 3}, 1fr)`, gap: 12, marginBottom: 20 }}>
                <div style={{ background: '#f0f9ff', borderRadius: 8, padding: 12, textAlign: 'center' }}>
                  <div style={{ fontSize: 24, fontWeight: 700, color: '#0369a1' }}>{overallStats.totalAssignees}</div>
                  <div style={{ fontSize: 12, color: '#475569' }}>Total Assignees</div>
                </div>
                <div style={{ background: '#f0fdf4', borderRadius: 8, padding: 12, textAlign: 'center' }}>
                  <div style={{ fontSize: 24, fontWeight: 700, color: '#16a34a' }}>{overallStats.avgCompletionRate}%</div>
                  <div style={{ fontSize: 12, color: '#475569' }}>Avg Completion Rate</div>
                </div>
                <div style={{ background: '#fffbeb', borderRadius: 8, padding: 12, textAlign: 'center' }}>
                  <div style={{ fontSize: 24, fontWeight: 700, color: '#d97706' }}>{overallStats.avgOnTimeRate}%</div>
                  <div style={{ fontSize: 12, color: '#475569' }}>Avg On-Time Rate</div>
                </div>
                {showFinancials && (
                  <div style={{ background: '#dbeafe', borderRadius: 8, padding: 12, textAlign: 'center' }}>
                    <div style={{ fontSize: 24, fontWeight: 700, color: '#1e40af' }}>PKR {overallStats.totalRevenue.toLocaleString()}</div>
                    <div style={{ fontSize: 12, color: '#475569' }}>Total Revenue</div>
                    <div style={{ fontSize: 11, color: '#475569', marginTop: 4 }}>{overallStats.collectionRate}% collected</div>
                  </div>
                )}
              </div>
            )}

            {/* Assignee Performance Table */}
            <div style={{ border: '1px solid #e2e8f0', borderRadius: 8, overflow: 'hidden' }}>
              <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
                <thead style={{ background: '#f1f5f9' }}>
                  <tr>
                    <th style={{ padding: '10px', textAlign: 'left', fontWeight: 600 }}>Assignee</th>
                    <th style={{ padding: '10px', textAlign: 'left', fontWeight: 600 }}>Dept</th>
                    <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Tasks</th>
                    <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Completion</th>
                    <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>On-Time</th>
                    {showFinancials && <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Revenue (PKR)</th>}
                    <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Performance</th>
                  </tr>
                </thead>
                <tbody>
                  {assigneeStats.map((stat, index) => {
                    // Calculate performance score
                    const performanceScore = Math.round(
                      (stat.completionRate * 0.4) +
                      (stat.onTimeRate * 0.3) +
                      ((100 - stat.overdueRate) * 0.2) +
                      (stat.collectionRate * 0.1)
                    );

                    // Performance color coding
                    let performanceColor = '#16a34a';
                    let performanceLabel = 'Excellent';

                    if (performanceScore < 60) {
                      performanceColor = '#dc2626';
                      performanceLabel = 'Needs Improvement';
                    } else if (performanceScore < 75) {
                      performanceColor = '#d97706';
                      performanceLabel = 'Satisfactory';
                    } else if (performanceScore < 90) {
                      performanceColor = '#2563eb';
                      performanceLabel = 'Good';
                    }

                    return (
                      <tr
                        key={index}
                        style={{ borderTop: '1px solid #e2e8f0', background: index % 2 === 0 ? '#fff' : '#f8fafc', cursor: 'pointer' }}
                        onClick={() => setSelectedAssigneeDetails(stat)}
                      >
                        <td style={{ padding: '10px', fontWeight: 600 }}>
                          {stat.name === 'Unassigned' ? (
                            <span style={{ color: '#94a3b8', fontStyle: 'italic' }}>{stat.name}</span>
                          ) : stat.name}
                        </td>
                        <td style={{ padding: '10px' }}>{stat.department}</td>
                        <td style={{ padding: '10px', textAlign: 'center' }}>
                          <div style={{ fontWeight: 600 }}>{stat.totalTasks}</div>
                          <div style={{ fontSize: 11, color: '#64748b' }}>
                            {stat.completedTasks}✓ {stat.pendingTasks}⏳
                          </div>
                        </td>
                        <td style={{ padding: '10px', textAlign: 'center' }}>
                          <div style={{ fontWeight: 600, color: stat.completionRate >= 80 ? '#16a34a' : stat.completionRate >= 60 ? '#d97706' : '#dc2626' }}>
                            {stat.completionRate}%
                          </div>
                          <div style={{ fontSize: 11, color: '#64748b' }}>
                            {stat.completedTasks}/{stat.totalTasks}
                          </div>
                        </td>
                        <td style={{ padding: '10px', textAlign: 'center' }}>
                          <div style={{ fontWeight: 600, color: stat.onTimeRate >= 80 ? '#16a34a' : stat.onTimeRate >= 60 ? '#d97706' : '#dc2626' }}>
                            {stat.onTimeRate}%
                          </div>
                          <div style={{ fontSize: 11, color: '#64748b' }}>
                            {stat.onTimeTasks}/{stat.completedTasks}
                          </div>
                        </td>
                        {showFinancials && (
                          <td style={{ padding: '10px', textAlign: 'center' }}>
                            <div style={{ fontWeight: 600 }}>PKR {stat.totalRevenue.toLocaleString()}</div>
                            <div style={{ fontSize: 11, color: '#64748b' }}>
                              {stat.collectionRate}% collected
                            </div>
                          </td>
                        )}
                        <td style={{ padding: '10px', textAlign: 'center' }}>
                          <div style={{
                            background: performanceColor + '20',
                            color: performanceColor,
                            padding: '4px 8px',
                            borderRadius: 999,
                            fontSize: 11,
                            fontWeight: 600,
                            display: 'inline-block'
                          }}>
                            {performanceLabel}
                          </div>
                          <div style={{ fontSize: 10, color: '#64748b', marginTop: 2 }}>
                            Score: {performanceScore}
                          </div>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>

          {/* Export button */}
          <div style={{ marginTop: 16, textAlign: 'right' }}>
            <button
              type="button"
              onClick={() => exportAssigneeReport(assigneeStats)}
              style={{ ...btnPrimarySmall, display: 'inline-flex', alignItems: 'center', gap: 6 }}
            >
              📊 Export Performance Report
            </button>
          </div>

          {/* Legend */}
          <div style={{ marginTop: 16, padding: 12, background: '#f8fafc', borderRadius: 8, fontSize: 11 }}>
            <div style={{ fontWeight: 600, marginBottom: 8, color: '#475569' }}>Performance Metrics Explained:</div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 8 }}>
              <div><span style={{ color: '#16a34a', fontWeight: 600 }}>Completion Rate:</span> Percentage of assigned tasks completed</div>
              <div><span style={{ color: '#16a34a', fontWeight: 600 }}>On-Time Rate:</span> Percentage of completed tasks delivered by deadline</div>
              <div><span style={{ color: '#dc2626', fontWeight: 600 }}>Overdue Rate:</span> Percentage of pending tasks past deadline</div>
              <div><span style={{ color: '#475569', fontWeight: 600 }}>Avg Days:</span> Average time taken to complete tasks</div>
              <div><span style={{ color: '#dc2626', fontWeight: 600 }}>High Priority:</span> Number of critical/urgent tasks assigned</div>
            </div>
          </div>

          {/* Assignee Details Modal */}
          {selectedAssigneeDetails && (
            <div className="confirmation-modal" onClick={() => { setSelectedAssigneeDetails(null); setModalStatusFilter('All'); }}>
              <div className="confirmation-content" style={{ width: 'min(1150px, 95vw)', maxHeight: '90vh', overflow: 'auto', textAlign: 'left' }} onClick={(e) => e.stopPropagation()}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
                  <h3 style={{ marginTop: 0 }}>{selectedAssigneeDetails.name}'s Tasks</h3>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <button
                      type="button"
                      onClick={() => setShowFinancials(!showFinancials)}
                      style={{
                        background: showFinancials ? '#3b82f6' : '#f1f5f9',
                        color: showFinancials ? '#fff' : '#475569',
                        border: '1px solid #cbd5e1',
                        borderRadius: 6,
                        padding: '4px 8px',
                        fontSize: 11,
                        cursor: 'pointer',
                        display: 'flex',
                        alignItems: 'center',
                        gap: 4
                      }}
                    >
                      {showFinancials ? '👁️ Hide PKR' : '👁️ Show PKR'}
                    </button>
                    <button type="button" onClick={() => { setSelectedAssigneeDetails(null); setModalStatusFilter('All'); }} style={{ background: 'none', border: 'none', fontSize: 18, cursor: 'pointer' }}>✕</button>
                  </div>
                </div>

                {/* Assignee Summary */}
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 20 }}>
                  <div style={{ textAlign: 'center', background: '#f0f9ff', padding: 12, borderRadius: 8 }}>
                    <div style={{ fontSize: 20, fontWeight: 700, color: '#0369a1' }}>{selectedAssigneeDetails.totalTasks}</div>
                    <div style={{ fontSize: 12, color: '#475569' }}>Total Tasks</div>
                    <div style={{ fontSize: 11, color: '#64748b', marginTop: 4 }}>Includes subtasks</div>
                  </div>
                  <div style={{ textAlign: 'center', background: '#f0fdf4', padding: 12, borderRadius: 8 }}>
                    <div style={{ fontSize: 20, fontWeight: 700, color: '#16a34a' }}>{selectedAssigneeDetails.completionRate}%</div>
                    <div style={{ fontSize: 12, color: '#475569' }}>Completion Rate</div>
                  </div>
                  <div style={{ textAlign: 'center', background: '#fffbeb', padding: 12, borderRadius: 8 }}>
                    <div style={{ fontSize: 20, fontWeight: 700, color: '#d97706' }}>{selectedAssigneeDetails.avgCompletionTime}d</div>
                    <div style={{ fontSize: 12, color: '#475569' }}>Avg Time</div>
                  </div>
                  {showFinancials && (
                    <div style={{ textAlign: 'center', background: '#dbeafe', padding: 12, borderRadius: 8 }}>
                      <div style={{ fontSize: 20, fontWeight: 700, color: '#1e40af' }}>PKR {selectedAssigneeDetails.totalRevenue.toLocaleString()}</div>
                      <div style={{ fontSize: 12, color: '#475569' }}>Total Revenue</div>
                      <div style={{ fontSize: 11, color: '#64748b', marginTop: 4 }}>Includes subtasks</div>
                    </div>
                  )}
                </div>

                {/* Modal Controls: Status Filter + Expand All */}
                <div style={{ marginBottom: 10, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                    <span style={{ fontSize: 12, color: '#475569', fontWeight: 600 }}>Status:</span>
                    <select
                      value={modalStatusFilter}
                      onChange={(e) => setModalStatusFilter(e.target.value)}
                      style={selectStyleXS}
                    >
                      <option value="All">All Status</option>
                      <option value="Completed">Completed</option>
                      <option value="In Progress">In Progress</option>
                      <option value="Not Started">Not Started</option>
                      <option value="Overdue">Overdue</option>
                    </select>
                  </div>
                  <button
                    type="button"
                    onClick={() => {
                      const assigneeTasks = filteredTasks.filter(t =>
                        t.assignee === selectedAssigneeDetails.name ||
                        (t.subtasks || []).some(s => s.assignee === selectedAssigneeDetails.name)
                      ).filter(t => {
                        if (modalStatusFilter === 'All') return true;
                        const mainMatches = (t.assignee === selectedAssigneeDetails.name) && (
                          (modalStatusFilter === 'Completed' && t.status === 'Completed') ||
                          (modalStatusFilter === 'In Progress' && t.status === 'In Progress') ||
                          (modalStatusFilter === 'Not Started' && t.status === 'Not Started') ||
                          (modalStatusFilter === 'Overdue' && t.is_overdue)
                        );
                        const anySubMatches = (t.subtasks || []).some(s =>
                          s.assignee === selectedAssigneeDetails.name && (
                            (modalStatusFilter === 'Completed' && (s.done || s.status === 'Completed')) ||
                            (modalStatusFilter === 'In Progress' && (!s.done && s.status !== 'Completed')) ||
                            (modalStatusFilter === 'Overdue' && t.is_overdue)
                          )
                        );
                        return mainMatches || anySubMatches;
                      });
                      const parentsWithSubs = assigneeTasks.filter(t => Array.isArray(t.subtasks) && t.subtasks.length > 0);
                      const allExpanded = parentsWithSubs.every(t => expandedAssigneeTasks[t.id]);

                      if (allExpanded) {
                        setExpandedAssigneeTasks({});
                      } else {
                        const next = {};
                        parentsWithSubs.forEach(t => { next[t.id] = true; });
                        setExpandedAssigneeTasks(next);
                      }
                    }}
                    style={{
                      background: '#f1f5f9',
                      border: '1px solid #cbd5e1',
                      borderRadius: 6,
                      padding: '4px 12px',
                      fontSize: 12,
                      cursor: 'pointer',
                      display: 'flex',
                      alignItems: 'center',
                      gap: 6
                    }}
                  >
                    {(() => {
                      const assigneeTasks = filteredTasks.filter(t =>
                        t.assignee === selectedAssigneeDetails.name ||
                        (t.subtasks || []).some(s => s.assignee === selectedAssigneeDetails.name)
                      ).filter(t => {
                        if (modalStatusFilter === 'All') return true;
                        const mainMatches = (t.assignee === selectedAssigneeDetails.name) && (
                          (modalStatusFilter === 'Completed' && t.status === 'Completed') ||
                          (modalStatusFilter === 'In Progress' && t.status === 'In Progress') ||
                          (modalStatusFilter === 'Not Started' && t.status === 'Not Started') ||
                          (modalStatusFilter === 'Overdue' && t.is_overdue)
                        );
                        const anySubMatches = (t.subtasks || []).some(s =>
                          s.assignee === selectedAssigneeDetails.name && (
                            (modalStatusFilter === 'Completed' && (s.done || s.status === 'Completed')) ||
                            (modalStatusFilter === 'In Progress' && (!s.done && s.status !== 'Completed')) ||
                            (modalStatusFilter === 'Overdue' && t.is_overdue)
                          )
                        );
                        return mainMatches || anySubMatches;
                      });
                      const parentsWithSubs = assigneeTasks.filter(t => Array.isArray(t.subtasks) && t.subtasks.length > 0);
                      const allExpanded = parentsWithSubs.every(t => expandedAssigneeTasks[t.id]);
                      return allExpanded ? '▼ Collapse All' : '▶ Expand All';
                    })()}
                  </button>
                </div>

                {/* Tasks Table with subtasks */}
                <div style={{ border: '1px solid #e2e8f0', borderRadius: 8, overflow: 'hidden' }}>
                  <table style={{ width: '100%', fontSize: 12, borderCollapse: 'collapse' }}>
                    <thead style={{ background: '#f1f5f9' }}>
                      <tr>
                        <th style={{ padding: '8px' }}>Type</th>
                        <th style={{ padding: '8px' }}>Client</th>
                        <th style={{ padding: '8px' }}>Task</th>
                        <th style={{ padding: '8px' }}>Due Date</th>
                        <th style={{ padding: '8px' }}>Status</th>
                        {showFinancials && <th style={{ padding: '8px' }}>Amount (PKR)</th>}
                        <th style={{ padding: '8px' }}>Invoice Status</th>
                      </tr>
                    </thead>
                    <tbody>
                      {(() => {
                        const assigneeTasks = filteredTasks.filter(t =>
                          t.assignee === selectedAssigneeDetails.name ||
                          (t.subtasks || []).some(s => s.assignee === selectedAssigneeDetails.name)
                        ).filter(t => {
                          if (modalStatusFilter === 'All') return true;

                          // Check main task status
                          const mainMatches = (t.assignee === selectedAssigneeDetails.name) && (
                            (modalStatusFilter === 'Completed' && t.status === 'Completed') ||
                            (modalStatusFilter === 'In Progress' && t.status === 'In Progress') ||
                            (modalStatusFilter === 'Not Started' && t.status === 'Not Started') ||
                            (modalStatusFilter === 'Overdue' && t.is_overdue)
                          );

                          // Check subtasks status
                          const anySubMatches = (t.subtasks || []).some(s =>
                            s.assignee === selectedAssigneeDetails.name && (
                              (modalStatusFilter === 'Completed' && (s.done || s.status === 'Completed')) ||
                              (modalStatusFilter === 'In Progress' && (!s.done && s.status !== 'Completed')) ||
                              // For overdue subtasks, we use the parent's is_overdue as a proxy or just skip if no sub-level logic
                              (modalStatusFilter === 'Overdue' && t.is_overdue)
                            )
                          );

                          return mainMatches || anySubMatches;
                        });

                        // Create array of all tasks including subtasks
                        const allTasks = [];
                        assigneeTasks.forEach((t, idx) => {
                          // Check if main task itself matches status (if it's assigned to this user)
                          const mainMatchesStatus = modalStatusFilter === 'All' || (
                            (t.assignee === selectedAssigneeDetails.name) && (
                              (modalStatusFilter === 'Completed' && t.status === 'Completed') ||
                              (modalStatusFilter === 'In Progress' && t.status === 'In Progress') ||
                              (modalStatusFilter === 'Not Started' && t.status === 'Not Started') ||
                              (modalStatusFilter === 'Overdue' && t.is_overdue)
                            )
                          );

                          // Add main task if it matches status OR if user only has subtasks that match status
                          // We usually show the parent even if it doesn't match, so subtasks can be seen under it
                          allTasks.push({
                            id: t.id,
                            isMain: true,
                            task: t,
                            idx: idx + 1
                          });

                          // Add subtasks if expanded
                          if (expandedAssigneeTasks[t.id] && t.subtasks && t.subtasks.length > 0) {
                            t.subtasks.forEach((s, subIdx) => {
                              const subMatchesStatus = modalStatusFilter === 'All' || (
                                (s.assignee === selectedAssigneeDetails.name) && (
                                  (modalStatusFilter === 'Completed' && (s.done || s.status === 'Completed')) ||
                                  (modalStatusFilter === 'In Progress' && (!s.done && s.status !== 'Completed')) ||
                                  (modalStatusFilter === 'Overdue' && t.is_overdue)
                                )
                              );

                              if (s.assignee === selectedAssigneeDetails.name && subMatchesStatus) {
                                allTasks.push({
                                  id: `${t.id}-sub-${subIdx}`,
                                  isMain: false,
                                  task: s,
                                  parentTask: t,
                                  idx: `${idx + 1}.${subIdx + 1}`
                                });
                              }
                            });
                          }
                        });

                        // Filter out main tasks that don't match status and have no subtasks that match status
                        const filteredAllTasks = allTasks.filter((item, i) => {
                          if (modalStatusFilter === 'All') return true;
                          if (!item.isMain) return true; // subtasks already filtered in the loop

                          // It's a main task. Check if it matches status.
                          const t = item.task;
                          const mainMatches = (t.assignee === selectedAssigneeDetails.name) && (
                            (modalStatusFilter === 'Completed' && t.status === 'Completed') ||
                            (modalStatusFilter === 'In Progress' && t.status === 'In Progress') ||
                            (modalStatusFilter === 'Not Started' && t.status === 'Not Started') ||
                            (modalStatusFilter === 'Overdue' && t.is_overdue)
                          );

                          // If main doesn't match, check if any follow-up task rows (subtasks) match
                          const hasMatchingSubtaskRows = allTasks.some(other =>
                            !other.isMain && other.parentTask?.id === t.id
                          );

                          return mainMatches || hasMatchingSubtaskRows;
                        });

                        return filteredAllTasks.map((item, idx) => {
                          const t = item.task;
                          const isMain = item.isMain;

                          return (
                            <tr
                              key={item.id}
                              style={{
                                borderTop: '1px solid #e2e8f0',
                                cursor: 'pointer',
                                background: isMain ? '#fff' : '#f8fafc'
                              }}
                              onClick={() => {
                                if (isMain) {
                                  onOpenTask && onOpenTask(t);
                                } else {
                                  onOpenTask && onOpenTask(item.parentTask);
                                }
                              }}
                            >
                              <td style={{ padding: '8px', width: 80 }}>
                                {isMain ? (
                                  <span style={{ fontSize: 11, color: '#475569', display: 'flex', alignItems: 'center', gap: 4 }}>
                                    {t.subtasks && t.subtasks.length > 0 && (
                                      <button
                                        onClick={(e) => {
                                          e.stopPropagation();
                                          setExpandedAssigneeTasks(prev => ({
                                            ...prev,
                                            [t.id]: !prev[t.id]
                                          }));
                                        }}
                                        style={{
                                          border: 'none',
                                          background: 'transparent',
                                          cursor: 'pointer',
                                          fontSize: 12,
                                          padding: 0,
                                          marginRight: 4
                                        }}
                                        title="Expand / collapse subtasks"
                                      >
                                        {expandedAssigneeTasks[t.id] ? '▼' : '▶'}
                                      </button>
                                    )}
                                    Main
                                  </span>
                                ) : (
                                  <span style={{ fontSize: 11, color: '#64748b', marginLeft: 20 }}>Subtask</span>
                                )}
                              </td>
                              <td style={{ padding: '8px' }}>
                                {isMain ?
                                  (clientsById[t.client_id]?.name || '—') :
                                  (clientsById[item.parentTask?.client_id]?.name || '—')
                                }
                              </td>
                              <td style={{ padding: '8px' }}>
                                {!isMain && <span style={{ marginRight: 6, opacity: 0.7 }}>↳</span>}
                                {t.title || t.task_description || (isMain ? 'Task' : 'Subtask')}
                              </td>
                              <td style={{ padding: '8px' }}>
                                {t.due_date ? fmtDDMMYY(t.due_date) :
                                  (t.start_date ? fmtDDMMYY(t.start_date) : '—')}
                              </td>
                              <td style={{ padding: '8px' }}>
                                <span style={{
                                  color: (t.status === 'Completed' || t.done) ? '#16a34a' :
                                    (t.is_overdue || (isMain && t.is_overdue)) ? '#dc2626' :
                                      (t.status === 'In Progress' || (isMain && t.status === 'In Progress')) ? '#2563eb' : '#64748b'
                                }}>
                                  {isMain ? (t.status || 'Not Started') : (t.done ? 'Completed' : (t.status || 'In Progress'))}
                                </span>
                              </td>
                              {showFinancials && (
                                <td style={{ padding: '8px', textAlign: 'right' }}>
                                  {t.invoice_amount ? `PKR ${Number(t.invoice_amount).toLocaleString()}` : '—'}
                                </td>
                              )}
                              <td style={{ padding: '8px' }}>
                                <span style={{
                                  color: t.invoice_status === 'Paid' ? '#16a34a' :
                                    t.invoice_status === 'Unpaid' ? '#dc2626' :
                                      t.invoice_status === 'Partially Paid' ? '#d97706' : '#64748b'
                                }}>
                                  {t.invoice_status || '—'}
                                </span>
                              </td>
                            </tr>
                          );
                        });
                      })()}
                    </tbody>
                  </table>
                </div>
              </div>
            </div>
          )}
        </div>
      );
    }

    /* ============================== Department Progress View =============================== */

    function DepartmentProgressView({ tasks, departmentFilter, isOwner, currentUser, clientsById, reportStatusFilter }) {
      // First, filter tasks based on user permissions
      let visibleTasks = tasks;

      if (!isOwner && currentUser?.department) {
        // Non-owners can only see tasks from their own department
        visibleTasks = tasks.filter(t =>
          t.department === currentUser.department ||
          (t.subtasks || []).some(s => s.department === currentUser.department)
        );
      }

      // Then apply status filter
      const filteredByStatus = visibleTasks.filter(t => {
        if (reportStatusFilter === 'All') return true;
        if (reportStatusFilter === 'Completed') return t.status === 'Completed';
        if (reportStatusFilter === 'Pending') return t.status !== 'Completed' && t.status !== 'Cancelled';
        if (reportStatusFilter === 'Overdue') return t.is_overdue;
        if (reportStatusFilter === 'In Progress') return t.status === 'In Progress';
        return true;
      });

      // Apply department filter
      const filteredTasks = departmentFilter === "All"
        ? filteredByStatus
        : filteredByStatus.filter(t => t.department === departmentFilter);

      // Group by department
      const departments = [...new Set(filteredTasks.map(t => t.department).filter(Boolean))].sort();

      // Calculate department statistics
      const departmentData = departments.map(dept => {
        const deptTasks = filteredTasks.filter(t => t.department === dept);
        const completed = deptTasks.filter(t => t.status === "Completed").length;
        const pending = deptTasks.filter(t => t.status !== "Completed" && t.status !== "Cancelled").length;
        const overdue = deptTasks.filter(t => t.is_overdue).length;
        const total = deptTasks.length;

        // Calculate revenue for this department
        const revenue = deptTasks.reduce((sum, t) => {
          const amount = Number(t.invoice_amount) || 0;
          return sum + amount;
        }, 0);

        const collected = deptTasks.reduce((sum, t) => {
          if (t.invoice_status === "Paid") {
            return sum + (Number(t.invoice_amount) || 0);
          }
          return sum;
        }, 0);

        return {
          name: dept,
          completed,
          pending,
          overdue,
          total,
          revenue,
          collected,
          collectionRate: revenue > 0 ? Math.round((collected / revenue) * 100) : 0,
          completionRate: total > 0 ? Math.round((completed / total) * 100) : 0
        };
      }).sort((a, b) => b.completionRate - a.completionRate);

      // Calculate overall totals
      const overallTotals = {
        totalTasks: filteredTasks.length,
        completed: filteredTasks.filter(t => t.status === "Completed").length,
        pending: filteredTasks.filter(t => t.status !== "Completed" && t.status !== "Cancelled").length,
        overdue: filteredTasks.filter(t => t.is_overdue).length,
        totalRevenue: filteredTasks.reduce((sum, t) => sum + (Number(t.invoice_amount) || 0), 0),
        collectedRevenue: filteredTasks.reduce((sum, t) =>
          t.invoice_status === "Paid" ? sum + (Number(t.invoice_amount) || 0) : sum, 0)
      };

      overallTotals.completionRate = overallTotals.totalTasks > 0
        ? Math.round((overallTotals.completed / overallTotals.totalTasks) * 100)
        : 0;
      overallTotals.collectionRate = overallTotals.totalRevenue > 0
        ? Math.round((overallTotals.collectedRevenue / overallTotals.totalRevenue) * 100)
        : 0;

      const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042', '#8884d8', '#82ca9d'];

      return (
        <div style={{ maxHeight: '60vh', overflow: 'auto' }}>
          {/* Overall KPIs */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 12, marginBottom: 20 }}>
            <div style={{ background: 'linear-gradient(135deg, #dbeafe, #93c5fd)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#1e40af' }}>{overallTotals.totalTasks}</div>
              <div style={{ fontSize: 12, color: '#3b82f6', fontWeight: 600 }}>Total Tasks</div>
              <div style={{ fontSize: 11, color: '#475569', marginTop: 4 }}>
                {overallTotals.completed}✓ {overallTotals.pending}⏳
              </div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #dcfce7, #86efac)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#166534' }}>{overallTotals.completionRate}%</div>
              <div style={{ fontSize: 12, color: '#16a34a', fontWeight: 600 }}>Completion Rate</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #fef3c7, #fcd34d)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#92400e' }}>{overallTotals.overdue}</div>
              <div style={{ fontSize: 12, color: '#d97706', fontWeight: 600 }}>Overdue Tasks</div>
            </div>
            <div style={{ background: 'linear-gradient(135deg, #e9d5ff, #d8b4fe)', borderRadius: 12, padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 24, fontWeight: 800, color: '#6d28d9' }}>PKR {overallTotals.totalRevenue.toLocaleString()}</div>
              <div style={{ fontSize: 12, color: '#8b5cf6', fontWeight: 600 }}>Total Revenue</div>
              <div style={{ fontSize: 11, color: '#475569', marginTop: 4 }}>{overallTotals.collectionRate}% collected</div>
            </div>
          </div>

          {/* Department Progress Chart */}
          <h4 style={{ margin: '20px 0 12px 0', fontSize: 14, color: '#475569' }}>Department Progress</h4>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20, marginBottom: 20 }}>
            <div style={{ background: '#fff', border: '1px solid #e2e8f0', borderRadius: 8, padding: 16 }}>
              <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 12, color: '#475569' }}>Completion Rate by Department</div>
              <ResponsiveContainer width="100%" height={200}>
                <BarChart data={departmentData}>
                  <CartesianGrid strokeDasharray="3 3" />
                  <XAxis dataKey="name" fontSize={11} />
                  <YAxis fontSize={11} />
                  <Tooltip formatter={(value) => [`${value}%`, 'Completion Rate']} />
                  <Bar dataKey="completionRate" fill="#3b82f6" />
                </BarChart>
              </ResponsiveContainer>
            </div>

            <div style={{ background: '#fff', border: '1px solid #e2e8f0', borderRadius: 8, padding: 16 }}>
              <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 12, color: '#475569' }}>Task Distribution</div>
              <ResponsiveContainer width="100%" height={200}>
                <PieChart>
                  <Pie
                    data={departmentData}
                    cx="50%"
                    cy="50%"
                    labelLine={false}
                    label={({ name, total }) => `${name}: ${total}`}
                    outerRadius={80}
                    fill="#8884d8"
                    dataKey="total"
                  >
                    {departmentData.map((entry, index) => (
                      <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
                    ))}
                  </Pie>
                  <Tooltip formatter={(value) => [value, 'Tasks']} />
                </PieChart>
              </ResponsiveContainer>
            </div>
          </div>

          {/* Department Details Table */}
          <div style={{ border: '1px solid #e2e8f0', borderRadius: 8, overflow: 'hidden', marginBottom: 20 }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
              <thead style={{ background: '#f1f5f9' }}>
                <tr>
                  <th style={{ padding: '10px', textAlign: 'left', fontWeight: 600 }}>Department</th>
                  <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Tasks</th>
                  <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Completed</th>
                  <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Pending</th>
                  <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Overdue</th>
                  <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Completion</th>
                  <th style={{ padding: '10px', textAlign: 'right', fontWeight: 600 }}>Revenue (PKR)</th>
                  <th style={{ padding: '10px', textAlign: 'center', fontWeight: 600 }}>Collection</th>
                </tr>
              </thead>
              <tbody>
                {departmentData.map((dept, idx) => (
                  <tr key={dept.name} style={{ borderTop: '1px solid #e2e8f0', background: idx % 2 === 0 ? '#fff' : '#f8fafc' }}>
                    <td style={{ padding: '10px', fontWeight: 600 }}>{dept.name}</td>
                    <td style={{ padding: '10px', textAlign: 'center' }}>
                      <div style={{ fontWeight: 600 }}>{dept.total}</div>
                      <div style={{ fontSize: 11, color: '#64748b' }}>
                        {dept.completed}✓ {dept.pending}⏳
                      </div>
                    </td>
                    <td style={{ padding: '10px', textAlign: 'center', color: '#16a34a', fontWeight: 600 }}>
                      {dept.completed}
                    </td>
                    <td style={{ padding: '10px', textAlign: 'center', color: '#f59e0b', fontWeight: 600 }}>
                      {dept.pending}
                    </td>
                    <td style={{ padding: '10px', textAlign: 'center', color: '#dc2626', fontWeight: 600 }}>
                      {dept.overdue}
                    </td>
                    <td style={{ padding: '10px', textAlign: 'center' }}>
                      <div style={{
                        background: dept.completionRate >= 80 ? '#dcfce7' : dept.completionRate >= 60 ? '#fef9c3' : '#fee2e2',
                        color: dept.completionRate >= 80 ? '#166534' : dept.completionRate >= 60 ? '#854d0e' : '#991b1b',
                        padding: '4px 8px',
                        borderRadius: 999,
                        fontSize: 11,
                        fontWeight: 600,
                        display: 'inline-block'
                      }}>
                        {dept.completionRate}%
                      </div>
                    </td>
                    <td style={{ padding: '10px', textAlign: 'right', fontWeight: 600 }}>
                      PKR {dept.revenue.toLocaleString()}
                      <div style={{ fontSize: 11, color: '#64748b' }}>
                        PKR {dept.collected.toLocaleString()} collected
                      </div>
                    </td>
                    <td style={{ padding: '10px', textAlign: 'center' }}>
                      <div style={{
                        background: dept.collectionRate >= 80 ? '#dcfce7' : dept.collectionRate >= 60 ? '#fef9c3' : '#fee2e2',
                        color: dept.collectionRate >= 80 ? '#166534' : dept.collectionRate >= 60 ? '#854d0e' : '#991b1b',
                        padding: '4px 8px',
                        borderRadius: 999,
                        fontSize: 11,
                        fontWeight: 600,
                        display: 'inline-block'
                      }}>
                        {dept.collectionRate}%
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      );
    }

    /* ============================== DatePicker =============================== */
    function DateWithPicker({ valueISO, onChangeISO, dense }) {
      const [show, setShow] = useState(false);
      const pickerRef = useRef(null);
      const value = valueISO ? toDate(valueISO) : null;
      const display = valueISO ? fmtDDMMYY(valueISO) : "";

      // Close picker when clicking outside
      useEffect(() => {
        function handleClickOutside(event) {
          if (pickerRef.current && !pickerRef.current.contains(event.target)) {
            setShow(false);
          }
        }
        document.addEventListener("mousedown", handleClickOutside);
        return () => {
          document.removeEventListener("mousedown", handleClickOutside);
        };
      }, []);

      return (
        <div style={{ position: "relative" }} ref={pickerRef}>
          <input
            value={display}
            onChange={e => {
              // Parse on type (dd-mm-yy)
              const iso = parseDDMMYY(e.target.value);
              if (iso) onChangeISO(iso);
            }}
            placeholder="dd-mm-yy"
            style={{ ...inputStyle, width: dense ? "100%" : "100%", ...(dense && { padding: "4px 8px", fontSize: "12px" }) }}
            onFocus={() => setShow(true)}
          />
          {show && (
            <div style={{ position: "absolute", top: "100%", left: 0, zIndex: 10, background: "#fff", boxShadow: "0 4px 12px rgba(0,0,0,0.15)", borderRadius: 10, padding: 10, marginTop: 4 }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 6 }}>
                <button type="button" onClick={() => { onChangeISO(toLocalISO(new Date())); setShow(false); }} style={btnSmall}>Today</button>
                <button type="button" onClick={() => setShow(false)} style={btnSmall}>Close</button>
              </div>
              <CalendarPicker value={value} onChange={d => { onChangeISO(toLocalISO(d)); setShow(false); }} />
            </div>
          )}
        </div>
      );
    }

    function DateMini({ valueStr, onChangeStr, dense }) {
      const iso = parseDDMMYY(valueStr);
      const display = iso ? fmtDDMMYY(iso) : valueStr;
      return (
        <input value={display} onChange={e => onChangeStr(e.target.value)} placeholder="dd-mm-yy" style={{ ...inputStyle, width: "100%", fontSize: dense ? 12 : 13 }} />
      );
    }

    function CalendarPicker({ value, onChange }) {
      const today = new Date(); today.setHours(0, 0, 0, 0);
      const [view, setView] = useState(() => value || today);
      const year = view.getFullYear(), month = view.getMonth();
      const first = new Date(year, month, 1);
      const last = new Date(year, month + 1, 0);
      const days = Array.from({ length: last.getDate() }, (_, i) => new Date(year, month, i + 1));
      const padStart = (first.getDay() + 6) % 7; // Mon=0, Sun=6
      const padEnd = 42 - (padStart + days.length);

      return (
        <div style={{ fontSize: 12 }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 6 }}>
            <button type="button" onClick={() => setView(d => { const x = new Date(d); x.setMonth(x.getMonth() - 1); return x; })} style={btnIconSmall}>◀</button>
            <div style={{ fontWeight: 600 }}>{view.toLocaleDateString(undefined, { month: "long", year: "numeric" })}</div>
            <button type="button" onClick={() => setView(d => { const x = new Date(d); x.setMonth(x.getMonth() + 1); return x; })} style={btnIconSmall}>▶</button>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 2, textAlign: "center" }}>
            {["M", "T", "W", "T", "F", "S", "S"].map(d => <div key={d} style={{ fontWeight: 600 }}>{d}</div>)}
            {Array(padStart).fill(null).map((_, i) => <div key={`pad-${i}`} style={{ height: 24 }}></div>)}
            {days.map((d, i) => {
              const isToday = d.getTime() === today.getTime();
              const isSelected = value && d.getTime() === value.getTime();
              return (
                <button
                  key={i}
                  type="button"
                  onClick={() => onChange(d)}
                  style={{
                    height: 24, display: "grid", placeItems: "center",
                    background: isSelected ? "#3b82f6" : isToday ? "#f0f9ff" : "transparent",
                    color: isSelected ? "#fff" : isToday ? "#0369a1" : "#0f172a",
                    border: isSelected ? "1px solid #3b82f6" : isToday ? "1px solid #0369a1" : "1px solid transparent",
                    borderRadius: 6,
                    fontSize: 11
                  }}
                >{d.getDate()}</button>
              );
            })}
            {Array(padEnd).fill(null).map((_, i) => <div key={`pad-end-${i}`} style={{ height: 24 }}></div>)}
          </div>
        </div>
      );
    }

    /* ============================== Components =============================== */
    function Card({ compact, color, title, onClick, active }) {
      return (
        <div
          style={{
            background: color || "#fff",
            borderRadius: 10,
            padding: compact ? "8px 10px" : "12px 14px",
            boxShadow: active ? "0 0 0 2px #3b82f6" : "0 1px 3px rgba(0,0,0,0.1)",
            cursor: onClick ? "pointer" : "default",
            textAlign: "center",
            fontWeight: 600,
            fontSize: compact ? 12 : 13,
            color: active ? "#1e40af" : "#0f172a",
            transition: "all .1s ease",
            transform: active ? "scale(0.97)" : "none",
            /* Prevent titles like "Quote Approved" and "Advance Received" from wrapping to the next line,
               which causes taller card heights.  Using nowrap keeps the tile height consistent across all
               KPIs regardless of label length. */
            whiteSpace: "nowrap"
          }}
          onClick={onClick}
        >{title}</div>
      );
    }

    // New Excel-style filter component
    function ExcelFilter({ small, label, value, onChange, options, disabled }) {
      const [isOpen, setIsOpen] = useState(false);
      const [selectedValues, setSelectedValues] = useState(() => {
        if (value === "All" || value === "") return [];
        if (Array.isArray(value)) return value;
        return [value];
      });

      const filterRef = useRef(null);

      // Close when clicking outside
      useEffect(() => {
        function handleClickOutside(event) {
          if (filterRef.current && !filterRef.current.contains(event.target)) {
            setIsOpen(false);
          }
        }
        document.addEventListener("mousedown", handleClickOutside);
        return () => document.removeEventListener("mousedown", handleClickOutside);
      }, []);

      // Update local state when prop changes
      useEffect(() => {
        if (value === "All" || value === "") {
          setSelectedValues([]);
        } else if (Array.isArray(value)) {
          setSelectedValues(value);
        } else {
          setSelectedValues([value]);
        }
      }, [value]);

      const handleCheckboxChange = (optionValue) => {
        let newSelected;
        if (selectedValues.includes(optionValue)) {
          newSelected = selectedValues.filter(v => v !== optionValue);
        } else {
          newSelected = [...selectedValues, optionValue];
        }
        setSelectedValues(newSelected);
      };

      const handleSelectAll = () => {
        const allValues = options.map(o => typeof o === "object" ? o.value : o);
        setSelectedValues(allValues);
      };

      const handleClearAll = () => {
        setSelectedValues([]);
      };

      const handleApply = () => {
        if (selectedValues.length === 0) {
          onChange("All");
        } else if (selectedValues.length === 1) {
          onChange(selectedValues[0]);
        } else {
          onChange(selectedValues);
        }
        setIsOpen(false);
      };

      // Get display text for button
      const getButtonText = () => {
        if (selectedValues.length === 0) return "All";
        if (selectedValues.length === 1) {
          const option = options.find(o => (typeof o === "object" ? o.value : o) === selectedValues[0]);
          return typeof option === "object" ? option.label : option;
        }
        return `${selectedValues.length} selected`;
      };

      return (
        <div style={{ position: "relative" }} ref={filterRef}>
          <label style={{ ...labelStyleSmall, display: "block", marginBottom: 2 }}>{label}</label>
          <button
            type="button"
            onClick={() => setIsOpen(!isOpen)}
            disabled={disabled}
            style={{
              ...selectStyle,
              height: small ? 28 : 34,
              fontSize: small ? 12 : 13,
              textAlign: "left",
              cursor: "pointer",
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              background: "#fff",
              paddingRight: "24px",
              position: "relative"
            }}
          >
            <span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
              {getButtonText()}
            </span>
            <span style={{ position: "absolute", right: 8, fontSize: "10px" }}>▼</span>
          </button>

          {isOpen && (
            <div style={{
              position: "absolute",
              top: "100%",
              left: 0,
              right: 0,
              zIndex: 1000,
              background: "#fff",
              border: "1px solid #cbd5e1",
              borderRadius: "6px",
              boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
              marginTop: "4px",
              maxHeight: "300px",
              overflowY: "auto",
              fontSize: small ? "12px" : "13px"
            }}>
              {/* Filter search for Client filter only */}
              {label === "Client" && (
                <div style={{ padding: "8px", borderBottom: "1px solid #e2e8f0" }}>
                  <input
                    type="text"
                    placeholder="Search clients..."
                    style={{
                      width: "100%",
                      padding: "4px 8px",
                      border: "1px solid #cbd5e1",
                      borderRadius: "4px",
                      fontSize: "12px"
                    }}
                    id={`client-search-${label}`}
                  />
                </div>
              )}

              <div style={{ padding: "8px", borderBottom: "1px solid #e2e8f0", display: "flex", justifyContent: "space-between" }}>
                <button
                  type="button"
                  onClick={handleSelectAll}
                  style={{
                    background: "none",
                    border: "none",
                    color: "#3b82f6",
                    cursor: "pointer",
                    fontSize: "11px",
                    padding: "2px 4px"
                  }}
                >
                  Select All
                </button>
                <button
                  type="button"
                  onClick={handleClearAll}
                  style={{
                    background: "none",
                    border: "none",
                    color: "#ef4444",
                    cursor: "pointer",
                    fontSize: "11px",
                    padding: "2px 4px"
                  }}
                >
                  Clear All
                </button>
              </div>

              <div style={{ maxHeight: "200px", overflowY: "auto" }}>
                {options.map(option => {
                  const optionValue = typeof option === "object" ? option.value : option;
                  const optionLabel = typeof option === "object" ? option.label : option;
                  const isChecked = selectedValues.includes(optionValue);

                  return (
                    <label
                      key={optionValue}
                      style={{
                        display: "flex",
                        alignItems: "center",
                        padding: "6px 8px",
                        cursor: "pointer",
                        borderBottom: "1px solid #f1f5f9"
                      }}
                      onMouseEnter={e => e.currentTarget.style.background = "#f8fafc"}
                      onMouseLeave={e => e.currentTarget.style.background = "#fff"}
                    >
                      <input
                        type="checkbox"
                        checked={isChecked}
                        onChange={() => handleCheckboxChange(optionValue)}
                        style={{ marginRight: "8px" }}
                      />
                      <span style={{ flex: 1 }}>{optionLabel}</span>
                    </label>
                  );
                })}
              </div>

              <div style={{ padding: "8px", borderTop: "1px solid #e2e8f0", textAlign: "right" }}>
                <button
                  type="button"
                  onClick={handleApply}
                  style={{
                    background: "#3b82f6",
                    color: "#fff",
                    border: "none",
                    borderRadius: "4px",
                    padding: "4px 12px",
                    fontSize: "12px",
                    cursor: "pointer"
                  }}
                >
                  OK
                </button>
              </div>
            </div>
          )}
        </div>
      );
    }

    // Keep the old Select component for backward compatibility
    function Select({ small, label, value, onChange, options, disabled }) {
      return (
        <div>
          <label style={{ ...labelStyleSmall, display: "block", marginBottom: 2 }}>{label}</label>
          <select value={value} onChange={e => onChange(e.target.value)} disabled={disabled} style={{ ...selectStyle, height: small ? 28 : 34, fontSize: small ? 12 : 13 }}>
            {options.map(o => typeof o === "object" ? <option key={o.value} value={o.value}>{o.label}</option> : <option key={o}>{o}</option>)}
          </select>
        </div>
      );
    }

    function Toggle({ active, onClick, children }) {
      return (
        <button
          type="button"
          onClick={onClick}
          style={{
            background: active ? "#3b82f6" : "#f1f5f9",
            color: active ? "#fff" : "#0f172a",
            border: "none",
            borderRadius: 6,
            padding: "4px 8px",
            fontSize: 12,
            cursor: "pointer",
          }}
        >{children}</button>
      );
    }

    function Field({ label, children, full }) {
      return (
        <div style={{ gridColumn: full ? "1 / -1" : "auto" }}>
          <label style={labelStyleSmall}>{label}</label>
          {children}
        </div>
      );
    }

    function Modal({ onClose, title, children, right, z = 50 }) {
      return (
        <div style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.5)", display: "grid", placeItems: "center", zIndex: z, padding: 16 }}>
          <div style={{ background: "#fff", borderRadius: 14, boxShadow: "0 10px 30px rgba(0,0,0,0.2)", maxWidth: "90vw", maxHeight: "90vh", overflow: "auto", width: "100%", minWidth: 300 }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "14px 16px", borderBottom: "1px solid #e2e8f0" }}>
              <h3 style={{ margin: 0, fontSize: 16 }}>{title}</h3>
              <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
                {right}
                <button type="button" onClick={onClose} style={{ ...btnIcon, fontSize: 18 }}>✕</button>
              </div>
            </div>
            <div style={{ padding: 16 }}>{children}</div>
          </div>
        </div>
      );
    }

    /* ============================== Styles =============================== */
    const cardStyle = {
      // Give the header an appealing subtle gradient instead of plain white
      background: "linear-gradient(135deg, #e0f2fe, #f0f9ff)",
      borderRadius: 12,
      boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
      padding: "10px 12px",
    };
    const cardLite = {
      background: "#fff",
      borderRadius: 10,
      boxShadow: "0 1px 2px rgba(0,0,0,0.05)",
      padding: 8,
    };

    const labelStyleSmall = {
      display: "block",
      fontSize: 11,
      fontWeight: 600,
      color: "#475569",
      marginBottom: 2,
      textTransform: "uppercase",
      letterSpacing: 0.5,
    };
    const controlHeight = {
      height: 34,
      width: "100%",
      border: "1px solid #cbd5e1",
      borderRadius: 8,
      padding: "0 10px",
      fontSize: 13,
      background: "#fff", boxSizing: "border-box"
    };
    const inputStyle = {
      ...controlHeight,
      background: "#fff",
    };
    const selectStyle = {
      ...controlHeight,
      background: "#fff",
    };
    const selectStyleXS = {
      ...controlHeight,
      height: 28,
      fontSize: 12,
      background: "#fff",
    };
    const selectStyleXS2 = {
      ...selectStyleXS,
      padding: "0 6px",
    };
    const thSlim = {
      padding: "6px 4px",
      fontSize: 11,
      fontWeight: 600,
      color: "#64748b",
      textTransform: "uppercase",
      whiteSpace: "nowrap",
    };
    const tdSlim = {
      padding: "8px 4px",
      fontSize: 13,
      verticalAlign: "top",
      // Prevent dates and short strings from wrapping inside the cell
      whiteSpace: "nowrap",
    };

    const btnBase = {
      border: "none",
      borderRadius: 8,
      padding: "6px 12px",
      fontSize: 13,
      fontWeight: 500,
      cursor: "pointer",
      display: "inline-flex",
      alignItems: "center",
      justifyContent: "center",
      gap: 4,
    };
    const btnSmall = {
      ...btnBase,
      padding: "4px 8px",
      fontSize: 12,
    };
    const btnPrimary = {
      ...btnBase,
      background: "#3b82f6",
      color: "#fff",
    };
    const btnPrimarySmall = {
      ...btnPrimary,
      padding: "4px 8px",
      fontSize: 12,
    };
    const btnDanger = {
      ...btnBase,
      background: "#ef4444",
      color: "#fff",
    };
    const btnDangerSmall = {
      ...btnDanger,
      padding: "4px 8px",
      fontSize: 12,
    };
    const btnDangerLine = {
      ...btnBase,
      background: "transparent",
      color: "#ef4444",
      border: "1px solid #ef4444",
    };
    const btnDangerIconSmall = {
      ...btnBase,
      background: "transparent",
      color: "#ef4444",
      padding: "2px 4px",
      fontSize: 12,
    };
    const btnIcon = {
      ...btnBase,
      background: "transparent",
      padding: 2,
    };
    const btnIconSmall = {
      ...btnIcon,
      fontSize: 12,
    };
    const btnDisabled = {
      ...btnBase,
      background: "#cbd5e1",
      color: "#64748b",
      cursor: "not-allowed",
    };

    // ============================== Render ================================
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <ErrorBoundary>
        <App />
      </ErrorBoundary>
    );

    // Calculate next start date based on recurrence pattern (advances from the previous start_date)
    function calculateNextStartDate(currentStartDate, recurrence) {
      if (!currentStartDate) return currentStartDate;
      const date = new Date(currentStartDate);
      switch (recurrence) {
        case "Weekly":
          date.setDate(date.getDate() + 7);
          break;
        case "Fortnightly":
          date.setDate(date.getDate() + 14);
          break;
        case "Monthly":
          date.setMonth(date.getMonth() + 1);
          break;
        case "Quarterly":
          date.setMonth(date.getMonth() + 3);
          break;
        default:
          return currentStartDate;
      }
      // Return ISO (YYYY-MM-DD) without timezone shift
      const y = date.getFullYear();
      const m = String(date.getMonth() + 1).padStart(2, '0');
      const d = String(date.getDate()).padStart(2, '0');
      return `${y}-${m}-${d}`;
    }
    /* ============================ REMINDERS MODAL ============================ */
    function RemindersModal({ task, subtask, subtaskIndex, onClose, onSave, clientsById, currentUser, fmtDDMMYY, uid }) {
      const [reminderNote, setReminderNote] = useState("");
      const [reminderDate, setReminderDate] = useState(todayISO());
      const [reminderMethod, setReminderMethod] = useState("Phone Call");

      // Get reminders from task or subtask
      const reminders = subtask ? (subtask.reminders || []) : (task.reminders || []);

      const addReminder = () => {
        if (!reminderNote.trim()) {
          alert("Please enter a reminder note");
          return;
        }

        const newReminder = {
          id: uid(),
          date: reminderDate,
          method: reminderMethod,
          note: reminderNote,
          addedBy: currentUser?.name || "Recovery Team",
          timestamp: new Date().toISOString()
        };

        // Create updated reminders array
        const updatedReminders = [...reminders, newReminder];

        // Call the save function with the updated reminders
        onSave(updatedReminders, subtask, subtaskIndex);

        // Reset form
        setReminderNote("");
        setReminderDate(todayISO());
        setReminderMethod("Phone Call");
      };

      const deleteReminder = (reminderId) => {
        if (!confirm("Delete this reminder?")) return;

        const updatedReminders = reminders.filter(r => r.id !== reminderId);
        onSave(updatedReminders, subtask, subtaskIndex);
      };

      return (
        <Modal z={160} onClose={onClose} title={subtask ? 'Subtask Reminders' : 'Task Reminders'}>
          <div style={{ maxHeight: '80vh', overflow: 'auto', textAlign: 'left' }}>
            {/* Task info */}
            <div style={{
              background: '#f8fafc',
              padding: '12px',
              borderRadius: '8px',
              marginBottom: '16px',
              fontSize: '12px'
            }}>
              <div><strong>Client:</strong> {clientsById[task.client_id]?.name || "—"}</div>
              <div><strong>Description:</strong> {subtask ? subtask.title : task.task_description}</div>
              <div><strong>Invoice Amount:</strong> PKR {(subtask ? subtask.invoice_amount : task.invoice_amount) || 0}</div>
              <div><strong>Balance:</strong> PKR {
                (() => {
                  const total = Number(subtask ? subtask.invoice_amount : task.invoice_amount) || 0;
                  const paid = Number(subtask ? subtask.paid_amount : task.paid_amount) || 0;
                  return (total - paid).toLocaleString();
                })()
              }</div>
            </div>

            {/* Add New Reminder Form */}
            <div style={{
              background: '#f0f9ff',
              padding: '16px',
              borderRadius: '8px',
              marginBottom: '16px'
            }}>
              <h4 style={{ margin: '0 0 12px 0', fontSize: '14px' }}>Add New Reminder</h4>

              <div style={{ display: 'grid', gap: '10px' }}>
                {/* Reminder Method */}
                <div>
                  <label style={{ fontSize: '12px', display: 'block', marginBottom: '4px' }}>Reminder Method:</label>
                  <select
                    value={reminderMethod}
                    onChange={(e) => setReminderMethod(e.target.value)}
                    style={{
                      width: '100%',
                      padding: '6px 8px',
                      border: '1px solid #cbd5e1',
                      borderRadius: '6px',
                      fontSize: '12px'
                    }}
                  >
                    <option value="Phone Call">📞 Phone Call</option>
                    <option value="WhatsApp">💬 WhatsApp</option>
                    <option value="Email">📧 Email</option>
                    <option value="SMS">📱 SMS</option>
                    <option value="In-Person">👥 In-Person</option>
                    <option value="Letter">📝 Letter</option>
                    <option value="Other">⚙️ Other</option>
                  </select>
                </div>

                {/* Reminder Date */}
                <div>
                  <label style={{ fontSize: '12px', display: 'block', marginBottom: '4px' }}>Date:</label>
                  <input
                    type="date"
                    value={reminderDate}
                    onChange={(e) => setReminderDate(e.target.value)}
                    style={{
                      width: '100%',
                      padding: '6px 8px',
                      border: '1px solid #cbd5e1',
                      borderRadius: '6px',
                      fontSize: '12px'
                    }}
                  />
                </div>

                {/* Reminder Note */}
                <div>
                  <label style={{ fontSize: '12px', display: 'block', marginBottom: '4px' }}>Reminder Note:</label>
                  <textarea
                    value={reminderNote}
                    onChange={(e) => setReminderNote(e.target.value)}
                    placeholder="e.g., First reminder given, client promised to pay by next week..."
                    style={{
                      width: '100%',
                      padding: '6px 8px',
                      border: '1px solid #cbd5e1',
                      borderRadius: '6px',
                      fontSize: '12px',
                      minHeight: '60px',
                      resize: 'vertical'
                    }}
                  />
                </div>

                {/* Add Button */}
                <button
                  type="button"
                  onClick={addReminder}
                  style={{
                    background: '#3b82f6',
                    color: 'white',
                    border: 'none',
                    padding: '8px 16px',
                    borderRadius: '6px',
                    fontSize: '12px',
                    cursor: 'pointer',
                    fontWeight: '600',
                    marginTop: '8px'
                  }}
                >
                  + Add Reminder
                </button>
              </div>
            </div>

            {/* Existing Reminders List */}
            <div>
              <h4 style={{ margin: '0 0 12px 0', fontSize: '14px' }}>
                Previous Reminders ({reminders.length})
              </h4>

              {reminders.length === 0 ? (
                <div style={{
                  textAlign: 'center',
                  padding: '20px',
                  color: '#64748b',
                  fontSize: '12px',
                  background: '#f8fafc',
                  borderRadius: '8px'
                }}>
                  No reminders added yet
                </div>
              ) : (
                <div style={{ maxHeight: '300px', overflow: 'auto' }}>
                  {reminders
                    .slice()
                    .sort((a, b) => new Date(b.date) - new Date(a.date))
                    .map((reminder, index) => (
                      <div
                        key={reminder.id}
                        style={{
                          background: index % 2 === 0 ? '#ffffff' : '#f8fafc',
                          padding: '12px',
                          borderRadius: '8px',
                          marginBottom: '8px',
                          border: '1px solid #e2e8f0',
                          fontSize: '12px'
                        }}
                      >
                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
                          <div>
                            <div style={{ fontWeight: '600', display: 'flex', alignItems: 'center', gap: '8px' }}>
                              <span>
                                {reminder.method === 'Phone Call' && '📞'}
                                {reminder.method === 'WhatsApp' && '💬'}
                                {reminder.method === 'Email' && '📧'}
                                {reminder.method === 'SMS' && '📱'}
                                {reminder.method === 'In-Person' && '👥'}
                                {reminder.method === 'Letter' && '📝'}
                                {reminder.method === 'Other' && '⚙️'}
                              </span>
                              <span>{reminder.method} Reminder</span>
                            </div>
                            <div style={{ fontSize: '11px', color: '#64748b', marginTop: '4px' }}>
                              Date: {fmtDDMMYY(reminder.date)} • Added by: {reminder.addedBy}
                            </div>
                          </div>

                          <button
                            type="button"
                            onClick={() => deleteReminder(reminder.id)}
                            style={{
                              background: '#fee2e2',
                              color: '#dc2626',
                              border: 'none',
                              padding: '4px 8px',
                              borderRadius: '4px',
                              fontSize: '11px',
                              cursor: 'pointer'
                            }}
                          >
                            Delete
                          </button>
                        </div>

                        <div style={{
                          marginTop: '8px',
                          padding: '8px',
                          background: index % 2 === 0 ? '#f8fafc' : '#ffffff',
                          borderRadius: '6px',
                          border: '1px solid #f1f5f9',
                          whiteSpace: 'pre-wrap'
                        }}>
                          {reminder.note}
                        </div>
                      </div>
                    ))}
                </div>
              )}
            </div>

            {/* Footer buttons */}
            <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '20px', gap: '8px' }}>
              <button
                type="button"
                onClick={onClose}
                style={{
                  background: '#f1f5f9',
                  color: '#475569',
                  border: '1px solid #cbd5e1',
                  padding: '8px 16px',
                  borderRadius: '6px',
                  fontSize: '12px',
                  cursor: 'pointer'
                }}
              >
                Close
              </button>
            </div>
          </div>
        </Modal>
      );
    }

  </script>
</body>

</html>