import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
import { Link } from 'react-router-dom';
import Layout from '../components/Layout';
import StatusBadge from '../components/StatusBadge';
import RequestForm from '../components/RequestForm';
import { supabase } from '../lib/supabase';
import { useAuth } from '../context/AuthContext';
import { readPageCache, writePageCache } from '../lib/pageCache';
import { withTimeout } from '../lib/withTimeout';
import { getCurrentVersionForTask, getDeadlineSourceSubmission } from '../lib/taskDeadlines';
import { logActivity } from '../lib/activityLog';
import { fmtShortDate } from '../lib/dates';
import { createInitialSubmissionForRequest, createTaskForRequest, findOrCreateProject } from '../lib/requestSubmission';
import { sendEmail } from '../lib/email';
import { uploadFilesToRequestInfo, createTaskFolder } from '../lib/filebrowserFolders';
import SortTh from '../components/SortTh';
import { useSortable } from '../hooks/useSortable';
import { popupOverlayStyle, popupSurfaceStyle } from '../lib/popupStyles';
import { useRefetchOnFocus } from '../hooks/useRefetchOnFocus';
import { useRealtimeSubscription } from '../hooks/useRealtimeSubscription';

const TASK_STAT_ICONS = {
  total: '<rect x="3" y="4" width="18" height="16" rx="2"/><line x1="7" y1="9" x2="17" y2="9"/><line x1="7" y1="13" x2="17" y2="13"/>',
  todo: '<circle cx="12" cy="12" r="8"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/>',
  progress: '<polyline points="4,14 10,8 14,12 20,6"/><line x1="20" y1="6" x2="20" y2="11"/><line x1="20" y1="6" x2="15" y2="6"/>',
  hold: '<rect x="7" y="6" width="3" height="12" rx="1"/><rect x="14" y="6" width="3" height="12" rx="1"/>',
  review: '<path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6z"/><circle cx="12" cy="12" r="2.5"/>',
  done: '<polyline points="4,12 9,17 20,6"/>',
};

const TASK_TABLE_TH_STYLE = { fontSize: 10, fontWeight: 500, textTransform: 'uppercase', letterSpacing: 0.6, color: 'var(--text-muted)', textAlign: 'left', padding: '0 0 12px 5px', border: 'none', background: 'transparent', verticalAlign: 'top' };
const TASK_TABLE_TD_BASE = { padding: '5px', border: 'none', background: 'transparent', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' };
const TASK_MODAL_TITLE_STYLE = { fontSize: 11, fontWeight: 500, textTransform: 'uppercase', letterSpacing: 0.8, color: 'var(--text-secondary)' };
const TASK_MODAL_LABEL_STYLE = { fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: 0.8, marginBottom: 6 };
const TASK_MODAL_INPUT_STYLE = { fontSize: 13, padding: '0 5px', textAlign: 'left', lineHeight: 1 };
const TASK_MODAL_BUTTON_STYLE = { lineHeight: 1, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' };
const TASK_MODAL_SHELL_STYLE = { ...popupSurfaceStyle, background: 'var(--card-bg)', width: 'min(720px, 96vw)', maxHeight: 'calc(100vh - 48px)', overflowY: 'auto' };
const PROJECT_MODAL_SHELL_STYLE = { ...popupSurfaceStyle, background: 'var(--card-bg)', width: 'min(434px, 100%)', maxHeight: 'calc(100vh - 48px)', overflowY: 'auto' };
const TASK_STATUS_SORT_RANK = { not_started: 0, in_progress: 1, on_hold: 2, client_review: 3, client_approved: 4, invoiced: 5, paid: 6 };

function TaskStatCard({ label, value, iconBg, iconColor, iconPath }) {
  return (
    <div style={{ background: 'var(--card-bg)', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)', border: '1px solid var(--border)', borderRadius: 8, padding: '14px 21px', minHeight: 86 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
        <div style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 5 }}>{label}</div>
        <div style={{ width: 27, height: 27, borderRadius: '50%', background: iconBg, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke={iconColor} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" dangerouslySetInnerHTML={{ __html: iconPath }} />
        </div>
      </div>
      <div style={{ fontSize: 30, fontWeight: 400, color: 'var(--text-primary)', letterSpacing: -0.5, lineHeight: 1.1 }}>{value}</div>
    </div>
  );
}

function TasksStatsRow({ tasks = [] }) {
  const toDo = tasks.filter(t => t?.status === 'not_started').length;
  const inProgress = tasks.filter(t => t?.status === 'in_progress').length;
  const onHold = tasks.filter(t => t?.status === 'on_hold').length;
  const inReview = tasks.filter(t => t?.status === 'client_review').length;
  const completed = tasks.filter(t => ['client_approved', 'invoiced', 'paid'].includes(t?.status)).length;
  return (
    <div className="dash-stat-grid" style={{ gridTemplateColumns: '1fr 1fr 1fr 1fr 1fr 1fr' }}>
      <TaskStatCard label="To Do"       value={toDo}       iconBg="rgba(167,139,250,0.15)" iconColor="#a78bfa" iconPath={TASK_STAT_ICONS.todo} />
      <TaskStatCard label="In Progress" value={inProgress}  iconBg="rgba(245,165,35,0.15)"  iconColor="#F5A523" iconPath={TASK_STAT_ICONS.progress} />
      <TaskStatCard label="On Hold"     value={onHold}      iconBg="rgba(239,68,68,0.15)"   iconColor="#ef4444" iconPath={TASK_STAT_ICONS.hold} />
      <TaskStatCard label="In Review"   value={inReview}    iconBg="rgba(96,165,250,0.15)"  iconColor="#60a5fa" iconPath={TASK_STAT_ICONS.review} />
      <TaskStatCard label="Completed"   value={completed}   iconBg="rgba(74,222,128,0.15)"  iconColor="#4ade80" iconPath={TASK_STAT_ICONS.done} />
      <TaskStatCard label="Total Tasks" value={tasks.length} iconBg="rgba(96,165,250,0.15)" iconColor="#60a5fa" iconPath={TASK_STAT_ICONS.total} />
    </div>
  );
}

function TasksPageShell({ statsTasks = [], projects = [], onAddProject = null, children }) {
  const [projSortKey, setProjSortKey] = useState('status');
  const [projSortDir, setProjSortDir] = useState('asc');
  const [projTab, setProjTab] = useState('active');
  const toggleProjSort = (col) => {
    if (projSortKey === col) setProjSortDir(d => d === 'asc' ? 'desc' : 'asc');
    else { setProjSortKey(col); setProjSortDir('asc'); }
  };
  const completedStatuses = new Set(['completed', 'cancelled', 'archived', 'done']);
  const projectTabs = [
    { id: 'all', label: 'All Projects' },
    { id: 'active', label: 'Active' },
    { id: 'completed', label: 'Completed' },
  ];
  const visibleProjects = projects.filter(p => {
    if (projTab === 'all') return true;
    const done = completedStatuses.has((p?.status || '').toLowerCase());
    return projTab === 'completed' ? done : !done;
  });
  const sortedProjects = [...visibleProjects].sort((a, b) => {
    if (projSortKey === 'status') {
      const ra = completedStatuses.has((a.status || '').toLowerCase()) ? 1 : 0;
      const rb = completedStatuses.has((b.status || '').toLowerCase()) ? 1 : 0;
      if (ra !== rb) return projSortDir === 'asc' ? ra - rb : rb - ra;
    }
    const av = (a.name || '').toLowerCase();
    const bv = (b.name || '').toLowerCase();
    return projSortDir === 'asc' ? av.localeCompare(bv) : bv.localeCompare(av);
  });
  const projectCompletionPct = (project) => {
    const pt = statsTasks.filter(t => t?.project_id === project?.id);
    if (pt.length > 0) {
      return Math.round((pt.filter(t => ['client_approved', 'invoiced', 'paid'].includes(t?.status)).length / pt.length) * 100);
    }
    const s = (project?.status || '').toLowerCase();
    if (s === 'completed' || s === 'done') return 100;
    if (s === 'cancelled' || s === 'archived') return 0;
    return 35;
  };
  return (
    <div style={{ minWidth: 0, flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
      <TasksStatsRow tasks={statsTasks} />
      <div style={{ display: 'flex', gap: 24, flex: 1, minHeight: 0, alignItems: 'stretch' }}>
        <div style={{ flex: '0 0 70%', minWidth: 0, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
          {children}
        </div>
        <div style={{ flex: '0 0 calc(30% - 24px)', minWidth: 0, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 10, flexShrink: 0 }}>
            {projectTabs.map(t => (
              <button key={t.id} onClick={() => setProjTab(t.id)} className={`section-tab-btn${projTab === t.id ? ' is-active' : ''}`}>{t.label}</button>
            ))}
            {onAddProject && (
              <div style={{ marginLeft: 'auto' }}>
                <button className="btn btn-outline" onClick={onAddProject}>+ Project</button>
              </div>
            )}
          </div>
          <div style={{ background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 8, padding: '18px 21px', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)', height: '100%', boxSizing: 'border-box', display: 'flex', flexDirection: 'column', minHeight: 0 }}>
            <div className="scrollbar-thin-theme table-scroll-fade table-scroll-hidden" style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
              <table className="table-sticky-head" style={{ width: '100%', borderCollapse: 'collapse', tableLayout: 'fixed' }}>
                <colgroup>
                  <col style={{ width: '60%' }} />
                  <col style={{ width: '40%' }} />
                </colgroup>
                <thead>
                  <tr>
                    <SortTh col="name" sortKey={projSortKey} sortDir={projSortDir} onSort={toggleProjSort} style={TASK_TABLE_TH_STYLE}>Name</SortTh>
                    <SortTh col="status" sortKey={projSortKey} sortDir={projSortDir} onSort={toggleProjSort} style={{ ...TASK_TABLE_TH_STYLE, textAlign: 'center' }}>Status</SortTh>
                  </tr>
                </thead>
                <tbody>
                  {sortedProjects.length === 0 ? (
                    <tr><td colSpan={2} style={{ fontSize: 13, color: 'var(--text-muted)', padding: '28px 5px', border: 'none', background: 'transparent', textAlign: 'center' }}>No projects.</td></tr>
                  ) : sortedProjects.map(p => (
                    <tr key={p.id}>
                      <td style={{ ...TASK_TABLE_TD_BASE, fontSize: 13, color: 'var(--text-primary)', textAlign: 'left' }}>
                        <Link to={`/projects/${p.id}`} className="table-link">{p.name}</Link>
                      </td>
                      <td style={{ ...TASK_TABLE_TD_BASE, fontSize: 12, color: 'var(--text-muted)', textAlign: 'center' }}>
                        <Link to={`/projects/${p.id}`} className="table-link" style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6, width: '100%' }}>
                          <span style={{ width: 68, height: 4, borderRadius: 2, background: 'var(--border)', overflow: 'hidden', position: 'relative', flexShrink: 0 }}>
                            <span style={{ position: 'absolute', inset: 0, width: `${projectCompletionPct(p)}%`, background: 'var(--accent)', borderRadius: 2 }} />
                          </span>
                          <span style={{ minWidth: 28, textAlign: 'right', fontSize: 12, color: 'var(--text-secondary)' }}>{projectCompletionPct(p)}%</span>
                        </Link>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export default function RequestsPage() {
  const { currentUser } = useAuth();
  const isTeam     = currentUser?.role === 'team';
  const isExternal = currentUser?.role === 'external';
  const isClient   = currentUser?.role === 'client';

  const [refreshKey, setRefreshKey] = useState(0);
  const refresh = useCallback(() => setRefreshKey(k => k + 1), []);
  useRefetchOnFocus(refresh);
  useRealtimeSubscription(['tasks', 'projects', 'submissions'], refresh);

  const teamCached = isTeam     ? readPageCache('team_requests') : null;
  const extCached  = isExternal ? readPageCache(`ext-requests:${currentUser?.id}`, 3 * 60_000) : null;

  const [projects,    setProjects]    = useState(() => teamCached?.projects    || extCached?.projects    || []);
  const [tasks,       setTasks]       = useState(() => teamCached?.tasks       || extCached?.tasks       || []);
  const [submissions, setSubmissions] = useState(() => teamCached?.submissions || extCached?.submissions || []);
  const [companies,   setCompanies]   = useState(() => teamCached?.companies   || []);
  const [loading, setLoading] = useState(() => {
    if (isTeam)     return !teamCached;
    if (isExternal) return !extCached;
    return true;
  });
  const [error,    setError]    = useState('');
  const [loadError, setLoadError] = useState(false);
  const [activeTab, setActiveTab] = useState('not_started');
  const [filterCompany, setFilterCompany] = useState('');
  const [filterProject, setFilterProject] = useState('');
  const { sortKey, sortDir, toggle, sort } = useSortable('status', 'asc');

  const [showAddForm,      setShowAddForm]      = useState(false);
  const [addFormKey,       setAddFormKey]       = useState(0);
  const [addSaving,        setAddSaving]        = useState(false);
  const [addError,         setAddError]         = useState('');
  const [uploadProgress,   setUploadProgress]   = useState({ active: false, label: '', percent: 0 });
  const [addRequestKey,    setAddRequestKey]    = useState(() => crypto.randomUUID());
  const [showAddProjectForm, setShowAddProjectForm] = useState(false);
  const [addProjectSaving,   setAddProjectSaving]   = useState(false);
  const [addProjectError,    setAddProjectError]    = useState('');
  const [addProjectForm,     setAddProjectForm]     = useState({ name: '', companyId: '' });
  const [companyFilterMenuOpen, setCompanyFilterMenuOpen] = useState(false);
  const companyFilterMenuRef = useRef(null);
  const [projectFilterMenuOpen, setProjectFilterMenuOpen] = useState(false);
  const projectFilterMenuRef = useRef(null);

  useEffect(() => {
    if (!companyFilterMenuOpen) return;
    function onDocClick(e) {
      if (companyFilterMenuRef.current && !companyFilterMenuRef.current.contains(e.target)) setCompanyFilterMenuOpen(false);
    }
    document.addEventListener('mousedown', onDocClick);
    return () => document.removeEventListener('mousedown', onDocClick);
  }, [companyFilterMenuOpen]);

  useEffect(() => {
    if (!projectFilterMenuOpen) return;
    function onDocClick(e) {
      if (projectFilterMenuRef.current && !projectFilterMenuRef.current.contains(e.target)) setProjectFilterMenuOpen(false);
    }
    document.addEventListener('mousedown', onDocClick);
    return () => document.removeEventListener('mousedown', onDocClick);
  }, [projectFilterMenuOpen]);

  useEffect(() => {
    let cancelled = false;
    async function loadTasksPage() {
      if (!currentUser?.id) { setLoading(false); return; }
      try {
        setError(''); setLoadError(false);

        let scopedProjectIds = null;
        let scopedTaskIds = null;

        if (isClient) {
          const clientCos = currentUser?.companies?.length ? currentUser.companies : (currentUser?.company ? [currentUser.company] : []);
          const companyIds = clientCos.map(c => c.id).filter(Boolean);
          if (companyIds.length > 0) {
            const { data: projRows } = await withTimeout(
              supabase.from('projects').select('id, tasks(id)').in('company_id', companyIds), 10000, 'Client project scope'
            );
            scopedProjectIds = (projRows || []).map(p => p.id);
            scopedTaskIds    = (projRows || []).flatMap(p => (p.tasks || []).map(t => t.id));
          } else {
            scopedProjectIds = []; scopedTaskIds = [];
          }
        }

        if (isExternal) {
          const { data: memberData } = await withTimeout(
            supabase.from('project_members').select('project_id').eq('profile_id', currentUser.id), 10000, 'External project scope'
          );
          scopedProjectIds = (memberData || []).map(r => r.project_id).filter(Boolean);
          if (scopedProjectIds.length > 0) {
            const { data: taskRows } = await withTimeout(
              supabase.from('tasks').select('id').in('project_id', scopedProjectIds), 10000, 'External task scope'
            );
            scopedTaskIds = (taskRows || []).map(r => r.id).filter(Boolean);
          } else {
            scopedTaskIds = [];
          }
        }

        const tasksQ = supabase.from('tasks')
          .select('id, title, status, current_version, project_id, assigned_name, assigned_to, invoiced, completed_at, submitted_at, assignee:profiles!assigned_to(avatar_url)')
          .order('submitted_at', { ascending: false });
        if (!isTeam) {
          if ((scopedProjectIds || []).length > 0) tasksQ.in('project_id', scopedProjectIds);
          else tasksQ.eq('id', '__none__');
        }

        const projectsQ = supabase.from('projects').select('id, name, status, company_id, company:companies(id, name)');
        if (!isTeam) {
          if ((scopedProjectIds || []).length > 0) projectsQ.in('id', scopedProjectIds);
          else projectsQ.eq('id', '__none__');
        }

        const subsQ = supabase.from('submissions')
          .select('id, task_id, submitted_at, submitted_by, submitted_by_name, is_hot, service_type, deadline, version_number, type')
          .order('submitted_at', { ascending: false });
        if (!isTeam) {
          if ((scopedTaskIds || []).length > 0) subsQ.in('task_id', scopedTaskIds);
          else subsQ.eq('id', '__none__');
        }

        const [{ data: subs }, { data: t }, { data: p }, { data: co }] = await withTimeout(
          Promise.all([subsQ, tasksQ, projectsQ, supabase.from('companies').select('id, name')]),
          15000, 'Tasks page load'
        );
        if (cancelled) return;

        setProjects(p || []); setTasks(t || []); setSubmissions(subs || []); setCompanies(co || []);

        if (isTeam) {
          writePageCache('team_requests', { submissions: subs || [], tasks: t || [], projects: p || [], companies: co || [] });
        } else if (isExternal) {
          writePageCache(`ext-requests:${currentUser.id}`, { projects: p || [], tasks: t || [], submissions: subs || [] });
        }
      } catch (err) {
        console.error('Tasks page load failed:', err);
        setError(err.message || 'Failed to load tasks.');
        setLoadError(true);
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    loadTasksPage();
    return () => { cancelled = true; };
  }, [isTeam, isExternal, isClient, currentUser?.id, refreshKey]); // eslint-disable-line react-hooks/exhaustive-deps

  const handleAddRequest = async (formData, _files, existingProjects) => {
    if (addSaving) return;
    setAddSaving(true); setAddError('');
    try {
      const resolvedProject = await findOrCreateProject(formData.companyId, formData.project.trim(), existingProjects);
      if (!projects.some(p => p.id === resolvedProject.id)) setProjects(prev => [...prev, resolvedProject]);
      const { task } = await createTaskForRequest({ projectId: resolvedProject.id, title: formData.title.trim(), requestKey: addRequestKey });
      if (!task) throw new Error('Failed to create task.');
      const taskCompany = companies?.find(c => c.id === formData.companyId);
      createTaskFolder(taskCompany?.name, resolvedProject.name, formData.title.trim()).catch(() => {});
      const { submission: sub } = await createInitialSubmissionForRequest({
        taskId: task.id, requestKey: addRequestKey, isHot: formData.isHot,
        serviceType: formData.serviceType, signFamily: formData.signFamily,
        signCount: formData.signCount, signs: formData.signs,
        deadline: formData.deadline,
        description: formData.description, submittedBy: formData.requestedBy, submittedByName: formData.requestedByName,
      });
      if (!sub) throw new Error('Failed to create submission.');
      logActivity({ actorId: currentUser.id, actorName: currentUser.name, action: 'request_submitted', taskId: task.id, taskTitle: task.title, projectId: resolvedProject.id, projectName: resolvedProject.name }).catch(() => {});
      const [{ data: newSubs }, { data: newTasks }] = await Promise.all([
        supabase.from('submissions').select('id, task_id, submitted_at, submitted_by, submitted_by_name, is_hot, service_type, deadline, version_number, type').order('submitted_at', { ascending: false }),
        supabase.from('tasks').select('id, title, status, current_version, project_id, assigned_name, assigned_to, invoiced, completed_at, submitted_at, assignee:profiles!assigned_to(avatar_url)').order('submitted_at', { ascending: false }),
      ]);
      setSubmissions(newSubs || []); setTasks(newTasks || []);
      setShowAddForm(false); setAddFormKey(k => k + 1); setAddRequestKey(crypto.randomUUID());
    } catch (err) { setAddError(err.message); }
    finally { setAddSaving(false); }
  };

  const handleClientRequest = async (formData, files, existingProjects) => {
    if (addSaving) return;
    setAddSaving(true); setAddError('');
    try {
      const clientCos = currentUser?.companies?.length ? currentUser.companies : (currentUser?.company ? [currentUser.company] : []);
      const selectedCompany = clientCos.find(c => c.id === formData.companyId);
      const resolvedProject = await findOrCreateProject(formData.companyId, formData.project.trim(), existingProjects);
      const { task } = await createTaskForRequest({ projectId: resolvedProject.id, title: formData.title.trim(), requestKey: addRequestKey });
      if (!task) throw new Error('Failed to create task.');
      createTaskFolder(selectedCompany?.name, resolvedProject.name, formData.title.trim()).catch(() => {});
      const { submission } = await createInitialSubmissionForRequest({
        taskId: task.id, requestKey: addRequestKey, isHot: formData.isHot,
        serviceType: formData.serviceType, signFamily: formData.signFamily,
        signCount: formData.signCount, signs: formData.signs,
        deadline: formData.deadline,
        description: formData.description, submittedBy: currentUser.id, submittedByName: currentUser.name,
      });
      if (submission && files.length > 0) {
        setShowAddForm(false);
        setUploadProgress({ active: true, label: 'Uploading files…', percent: 0 });
        for (let fi = 0; fi < files.length; fi++) {
          const file = files[fi];
          setUploadProgress({ active: true, label: file.name, percent: Math.round((fi / files.length) * 100) });
          const path = `${task.id}/${Date.now()}_${file.name}`;
          const { data: uploaded, error: uploadError } = await supabase.storage.from('submissions').upload(path, file);
          if (uploadError) { await supabase.from('tasks').delete().eq('id', task.id); setUploadProgress({ active: false, label: '', percent: 0 }); throw new Error(`Upload failed: ${uploadError.message}`); }
          if (uploaded) {
            const { error: fileErr } = await supabase.from('submission_files').insert({ submission_id: submission.id, name: file.name, storage_path: path, size: file.size });
            if (fileErr) { await supabase.from('tasks').delete().eq('id', task.id); setUploadProgress({ active: false, label: '', percent: 0 }); throw new Error(`File record failed: ${fileErr.message}`); }
          }
        }
        uploadFilesToRequestInfo(files, selectedCompany?.name, resolvedProject.name, formData.title.trim()).catch(() => {});
        setUploadProgress({ active: false, label: '', percent: 0 });
      }
      logActivity({ actorId: currentUser.id, actorName: currentUser.name, action: 'request_submitted', taskId: task.id, taskTitle: task.title, projectId: resolvedProject.id, projectName: resolvedProject.name }).catch(() => {});
      sendEmail('new_request', 'hello@fourgebranding.com', {
        clientName: currentUser.name, clientEmail: currentUser.email,
        company: selectedCompany?.name || '', serviceType: formData.serviceType,
        projectName: formData.project, deadline: formData.deadline,
        description: formData.description, taskId: task.id,
      }).catch(() => {});
      const refreshCompanyIds = clientCos.map(c => c.id).filter(Boolean);
      const { data: refreshProjects } = await supabase.from('projects').select('id, name, status, company_id, company:companies(id, name)').in('company_id', refreshCompanyIds);
      const refreshProjectIds = (refreshProjects || []).map(p => p.id);
      const { data: newTasks } = await supabase.from('tasks')
        .select('id, title, status, current_version, project_id, assigned_name, assigned_to, invoiced, completed_at, submitted_at, assignee:profiles!assigned_to(avatar_url)')
        .in('project_id', refreshProjectIds.length > 0 ? refreshProjectIds : ['__none__'])
        .order('submitted_at', { ascending: false });
      const refreshTaskIds = (newTasks || []).map(t => t.id);
      const { data: newSubs } = await supabase.from('submissions')
        .select('id, task_id, submitted_at, submitted_by, submitted_by_name, is_hot, service_type, deadline, version_number, type')
        .in('task_id', refreshTaskIds.length > 0 ? refreshTaskIds : ['__none__'])
        .order('submitted_at', { ascending: false });
      setProjects(refreshProjects || []); setTasks(newTasks || []); setSubmissions(newSubs || []);
      setShowAddForm(false); setAddFormKey(k => k + 1); setAddRequestKey(crypto.randomUUID());
    } catch (err) { setAddError(err.message); }
    finally { setAddSaving(false); }
  };

  const handleAddProject = async (e) => {
    e.preventDefault();
    if (addProjectSaving) return;
    setAddProjectSaving(true); setAddProjectError('');
    try {
      const name = addProjectForm.name.trim();
      if (!name) throw new Error('Project name required.');
      if (!addProjectForm.companyId) throw new Error('Company required.');
      const { data: newProject, error: insertError } = await supabase
        .from('projects').insert({ name, company_id: addProjectForm.companyId, status: 'active' })
        .select('id, name, status, company_id, company:companies(id, name)').single();
      if (insertError) throw insertError;
      setProjects(prev => [...prev, newProject]);
      setShowAddProjectForm(false); setAddProjectForm({ name: '', companyId: '' });
    } catch (err) { setAddProjectError(err.message || 'Failed to create project.'); }
    finally { setAddProjectSaving(false); }
  };

  // Companies available for filter menu and forms
  const filterableCompanies = useMemo(() => {
    if (isClient) {
      const cos = currentUser?.companies?.length ? currentUser.companies : (currentUser?.company ? [currentUser.company] : []);
      return cos.slice().sort((a, b) => a.name.localeCompare(b.name));
    }
    return companies.slice().sort((a, b) => (a.name || '').localeCompare(b.name || ''));
  }, [isClient, companies, currentUser]); // eslint-disable-line react-hooks/exhaustive-deps

  // Normalize all tasks to a common row shape for unified table render
  const allRows = useMemo(() => {
    if (isClient) {
      return tasks.map(task => {
        const sub = submissions.find(s => s.task_id === task.id && s.type === 'initial');
        return {
          id: task.id, title: task.title, status: task.status, projectId: task.project_id,
          serviceType: sub?.service_type || '—', deadline: sub?.deadline || null,
          version: task.current_version || 0, isHot: false,
          assignedName: task.assigned_name || null, assigneeAvatar: task.assignee?.avatar_url || null, assignedTo: task.assigned_to || null,
          submittedAt: task.submitted_at ? new Date(task.submitted_at).getTime() : 0,
        };
      });
    }
    return tasks.map(task => {
      const taskSubs = submissions.filter(s => s.task_id === task.id);
      const deadlineSource = getDeadlineSourceSubmission(task, taskSubs);
      if (!deadlineSource) return null;
      const currentVersion = getCurrentVersionForTask(task, taskSubs);
      const latestGroup = taskSubs.filter(s => s.version_number === currentVersion);
      const serviceType = submissions.find(s => s.task_id === task.id && s.type === 'initial')?.service_type
        || submissions.find(s => s.task_id === task.id && s.service_type)?.service_type
        || deadlineSource.service_type || '—';
      return {
        id: task.id, title: task.title, status: task.status, projectId: task.project_id,
        serviceType, deadline: deadlineSource.deadline,
        version: deadlineSource.version_number ?? 0,
        isHot: deadlineSource.is_hot || false,
        assignedName: task.assigned_name || null, assigneeAvatar: task.assignee?.avatar_url || null, assignedTo: task.assigned_to || null,
        submittedAt: latestGroup.length > 0
          ? Math.max(...latestGroup.map(s => new Date(s.submitted_at).getTime()))
          : (task.submitted_at ? new Date(task.submitted_at).getTime() : 0),
      };
    }).filter(Boolean);
  }, [tasks, submissions, isClient]); // eslint-disable-line react-hooks/exhaustive-deps

  const filteredRows = useMemo(() => {
    return allRows
      .filter(row => {
        const project = projects.find(p => p.id === row.projectId);
        if (filterCompany && project?.company_id !== filterCompany) return false;
        if (filterProject && row.projectId !== filterProject) return false;
        return true;
      })
      .sort((a, b) => b.submittedAt - a.submittedAt);
  }, [allRows, projects, filterCompany, filterProject]);

  const doneStatuses = new Set(['client_approved', 'invoiced', 'paid']);

  const tabs = [
    { id: 'all',           label: 'All Tasks'   },
    { id: 'not_started',   label: 'To Do'        },
    { id: 'in_progress',   label: 'In Progress'  },
    { id: 'on_hold',       label: 'On Hold'      },
    { id: 'client_review', label: 'In Review'    },
    { id: 'completed',     label: 'Completed'    },
  ];

  const tabRows = activeTab === 'all'       ? filteredRows
    : activeTab === 'completed' ? filteredRows.filter(r => doneStatuses.has(r.status))
    : filteredRows.filter(r => r.status === activeTab);

  const sortedRows = sort(tabRows, (row, key) => {
    if (key === 'title')       return row.title || '';
    if (key === 'project')     return projects.find(p => p.id === row.projectId)?.name || '';
    if (key === 'serviceType') return row.serviceType || '';
    if (key === 'revision')    return row.version ?? 0;
    if (key === 'deadline')    return row.deadline || '';
    if (key === 'status')      return TASK_STATUS_SORT_RANK[row.status] ?? 99;
    if (key === 'submitted_at') return row.submittedAt || 0;
    if (key === 'assigned')    return row.assignedName || '';
    if (key === 'priority')    return row.isHot ? 0 : 1;
    return '';
  });

  const projectOptions = useMemo(() => {
    if (!isExternal) return [];
    return [...new Map(
      allRows.map(r => projects.find(p => p.id === r.projectId)).filter(Boolean).map(p => [p.id, p])
    ).values()];
  }, [isExternal, allRows, projects]); // eslint-disable-line react-hooks/exhaustive-deps


  const renderRow = (row) => {
    const project = projects.find(p => p.id === row.projectId);
    const initials = row.assignedName ? row.assignedName.split(' ').map(n => n[0]).join('').slice(0, 2).toUpperCase() : null;
    return (
      <tr key={row.id}>
        <td style={{ ...TASK_TABLE_TD_BASE, fontSize: 12, color: 'var(--text-primary)', fontVariantNumeric: 'tabular-nums' }}>
          {`R${String(row.version).padStart(2, '0')}`}
        </td>
        <td style={{ ...TASK_TABLE_TD_BASE, fontSize: 13, color: 'var(--text-primary)' }}>
          <Link to={`/tasks/${row.id}`} className="table-link">{row.title || '—'}</Link>
        </td>
        <td style={{ ...TASK_TABLE_TD_BASE, fontSize: 13, color: 'var(--text-primary)' }}>
          {project ? <Link to={`/projects/${project.id}`} className="table-link">{project.name}</Link> : '—'}
        </td>
        <td style={{ ...TASK_TABLE_TD_BASE, textAlign: 'center' }}>
          {(() => {
            const avatarStyle = { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 26, height: 26, borderRadius: '50%', overflow: 'hidden', verticalAlign: 'middle', flexShrink: 0 };
            if (row.assignedName && row.assignedTo) {
              const portrait = row.assigneeAvatar
                ? <div title={row.assignedName} style={avatarStyle}><img src={row.assigneeAvatar} alt={row.assignedName} style={{ width: '100%', height: '100%', objectFit: 'cover' }} /></div>
                : <div title={row.assignedName} style={{ ...avatarStyle, background: 'var(--accent)' }}><span style={{ fontSize: 10, fontWeight: 600, color: '#000', lineHeight: 1 }}>{initials}</span></div>;
              return <Link to={`/profile/${row.assignedTo}`} style={{ display: 'inline-flex' }}>{portrait}</Link>;
            }
            return <div title="Unassigned" style={{ ...avatarStyle, background: 'rgba(255,255,255,0.08)' }}><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,0.3)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg></div>;
          })()}
        </td>
        <td style={{ ...TASK_TABLE_TD_BASE, fontSize: 11, textAlign: 'center', color: row.isHot ? '#ef4444' : 'var(--text-primary)', textTransform: 'uppercase', letterSpacing: 0.5 }}>
          {row.isHot ? 'HOT' : 'NO'}
        </td>
        <td style={{ ...TASK_TABLE_TD_BASE, fontSize: 12, color: 'var(--text-primary)', textAlign: 'center' }}>
          {row.serviceType}
        </td>
        <td style={{ ...TASK_TABLE_TD_BASE, fontSize: 12, color: 'var(--text-primary)', textAlign: 'center' }}>
          {fmtShortDate(row.deadline, 'Not specified')}
        </td>
      </tr>
    );
  };

  if (loading)   return <Layout><p style={{ padding: 24, color: 'var(--text-muted)' }}>Loading...</p></Layout>;
  if (loadError) return <Layout><div style={{ padding: 24 }}><p style={{ color: 'var(--text-muted)', marginBottom: 12 }}>Failed to load. Check your connection and try again.</p><button className="btn btn-outline" onClick={() => window.location.reload()}>Retry</button></div></Layout>;

  const filteredStatTasks    = filteredRows.map(r => tasks.find(t => t.id === r.id)).filter(Boolean);
  const filteredProjectsShell = filterCompany ? projects.filter(p => p.company_id === filterCompany) : projects;

  return (
    <Layout>
      <TasksPageShell
        statsTasks={filteredStatTasks}
        projects={filteredProjectsShell}
        onAddProject={(isTeam || isClient) ? () => {
          setAddProjectForm(f => ({ ...f, companyId: !isTeam && filterableCompanies.length === 1 ? filterableCompanies[0].id : f.companyId }));
          setShowAddProjectForm(true); setAddProjectError('');
        } : null}
      >
        {/* Add project modal */}
        {showAddProjectForm && (
          <div style={popupOverlayStyle} onClick={() => { setShowAddProjectForm(false); setAddProjectForm({ name: '', companyId: '' }); setAddProjectError(''); }}>
            <div style={PROJECT_MODAL_SHELL_STYLE} onClick={e => e.stopPropagation()}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, marginBottom: 14 }}>
                <div style={TASK_MODAL_TITLE_STYLE}>Add Project</div>
              </div>
              <form onSubmit={handleAddProject}>
                <div className="form-group">
                  <label style={TASK_MODAL_LABEL_STYLE}>Company *</label>
                  <select value={addProjectForm.companyId} onChange={e => setAddProjectForm(f => ({ ...f, companyId: e.target.value }))} required style={TASK_MODAL_INPUT_STYLE}>
                    <option value="">Select company...</option>
                    {filterableCompanies.map(co => <option key={co.id} value={co.id}>{co.name}</option>)}
                  </select>
                </div>
                <div className="form-group">
                  <label style={TASK_MODAL_LABEL_STYLE}>Project Name *</label>
                  <input type="text" placeholder="e.g. Brand Identity 2026" value={addProjectForm.name} onChange={e => setAddProjectForm(f => ({ ...f, name: e.target.value }))} required autoFocus style={TASK_MODAL_INPUT_STYLE} />
                </div>
                {addProjectError && <div style={{ fontSize: 13, color: 'var(--danger)', marginBottom: 12 }}>{addProjectError}</div>}
                <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 20 }}>
                  <button type="submit" className="btn btn-outline" style={TASK_MODAL_BUTTON_STYLE} disabled={addProjectSaving}>{addProjectSaving ? 'Saving...' : 'Save'}</button>
                  <button type="button" className="btn btn-outline" style={TASK_MODAL_BUTTON_STYLE} onClick={() => { setShowAddProjectForm(false); setAddProjectForm({ name: '', companyId: '' }); setAddProjectError(''); }}>Cancel</button>
                </div>
              </form>
            </div>
          </div>
        )}

        {/* Add task modal */}
        {showAddForm && (
          <div style={popupOverlayStyle} onClick={() => { setShowAddForm(false); setAddFormKey(k => k + 1); setAddError(''); }}>
            <div style={TASK_MODAL_SHELL_STYLE} onClick={e => e.stopPropagation()}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, marginBottom: 14 }}>
                <div style={TASK_MODAL_TITLE_STYLE}>{isTeam ? 'Add Task' : 'New Task'}</div>
              </div>
              <RequestForm
                key={addFormKey}
                companies={isTeam ? companies : filterableCompanies}
                initialCompanyId={!isTeam && filterableCompanies.length === 1 ? filterableCompanies[0].id : ''}
                currentUser={currentUser}
                showRequester={isTeam}
                onSubmit={isTeam ? handleAddRequest : handleClientRequest}
                onCancel={() => { setShowAddForm(false); setAddFormKey(k => k + 1); setAddError(''); }}
                saving={addSaving}
                error={addError}
                submitLabel="Save"
              />
            </div>
          </div>
        )}

        {/* Controls bar: tabs left, filters + actions right */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 10, flexShrink: 0 }}>
          {tabs.map(t => (
            <button key={t.id} onClick={() => setActiveTab(t.id)} className={`section-tab-btn${activeTab === t.id ? ' is-active' : ''}`}>
              {t.label}
            </button>
          ))}
          <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 8 }} ref={companyFilterMenuRef}>
            {(isTeam || isClient) && (
              <button className="btn btn-outline" onClick={() => { setShowAddForm(s => !s); setAddError(''); }}>+ Task</button>
            )}
            {isExternal && projectOptions.length > 0 && (
              <div style={{ position: 'relative', display: 'flex', alignItems: 'center' }} ref={projectFilterMenuRef}>
                <button
                  className="btn btn-outline"
                  aria-label="Filter projects" title="Filter projects"
                  onClick={() => setProjectFilterMenuOpen(o => !o)}
                  style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}
                >
                  <svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M2 4h12M4 8h8M6 12h4" />
                  </svg>
                </button>
                {projectFilterMenuOpen && (
                  <div className="site-header-avatar-menu" style={{ position: 'absolute', top: 'calc(100% + 4px)', right: 0, zIndex: 220, minWidth: 170 }}>
                    <button onClick={() => { setFilterProject(''); setProjectFilterMenuOpen(false); }} className="site-header-avatar-item" style={{ background: !filterProject ? 'rgba(245,165,35,0.08)' : 'transparent', color: !filterProject ? 'var(--accent)' : 'var(--text-primary)' }}>All Projects</button>
                    {projectOptions.map(p => (
                      <button key={p.id} onClick={() => { setFilterProject(p.id); setProjectFilterMenuOpen(false); }} className="site-header-avatar-item" style={{ background: filterProject === p.id ? 'rgba(245,165,35,0.08)' : 'transparent', color: filterProject === p.id ? 'var(--accent)' : 'var(--text-primary)' }}>{p.name}</button>
                    ))}
                  </div>
                )}
              </div>
            )}
            {(isTeam || isClient) && (
              <div style={{ position: 'relative', display: 'flex', alignItems: 'center' }}>
                <button
                  className="btn btn-outline"
                  aria-label="Filter companies" title="Filter companies"
                  onClick={() => setCompanyFilterMenuOpen(o => !o)}
                  style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}
                >
                  <svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M2 4h12M4 8h8M6 12h4" />
                  </svg>
                </button>
                {companyFilterMenuOpen && (
                  <div className="site-header-avatar-menu" style={{ position: 'absolute', top: 'calc(100% + 4px)', right: 0, zIndex: 220, minWidth: 170 }}>
                    <button
                      onClick={() => { setFilterCompany(''); setFilterProject(''); setCompanyFilterMenuOpen(false); }}
                      className="site-header-avatar-item"
                      style={{ background: !filterCompany ? 'rgba(245,165,35,0.08)' : 'transparent', color: !filterCompany ? 'var(--accent)' : 'var(--text-primary)' }}
                    >All Companies</button>
                    {filterableCompanies.map(co => (
                      <button
                        key={co.id}
                        onClick={() => { setFilterCompany(co.id); setFilterProject(''); setCompanyFilterMenuOpen(false); }}
                        className="site-header-avatar-item"
                        style={{ background: filterCompany === co.id ? 'rgba(245,165,35,0.08)' : 'transparent', color: filterCompany === co.id ? 'var(--accent)' : 'var(--text-primary)' }}
                      >{co.name}</button>
                    ))}
                  </div>
                )}
              </div>
            )}
          </div>
        </div>

        {/* Task table */}
        <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', background: 'var(--card-bg)', borderRadius: 8, border: '1px solid var(--border)', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)', padding: '18px 21px' }}>
          {allRows.length === 0 ? (
            <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 13, color: 'var(--text-muted)' }}>No tasks yet.</div>
          ) : sortedRows.length === 0 ? (
            <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 13, color: 'var(--text-muted)' }}>No tasks.</div>
          ) : (
            <div className="scrollbar-thin-theme table-scroll-fade table-scroll-hidden" style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
              <table className="table-sticky-head table-no-row-hover" style={{ tableLayout: 'fixed', borderCollapse: 'collapse', width: '100%' }}>
                <colgroup>
                  <col style={{ width: '5%' }} />
                  <col style={{ width: '25%' }} />
                  <col style={{ width: '18%' }} />
                  <col style={{ width: '15%' }} />
                  <col style={{ width: '7%' }} />
                  <col style={{ width: '15%' }} />
                  <col style={{ width: '15%' }} />
                </colgroup>
                <thead>
                  <tr>
                    <SortTh col="revision"    sortKey={sortKey} sortDir={sortDir} onSort={toggle} style={TASK_TABLE_TH_STYLE}>R#</SortTh>
                    <SortTh col="title"       sortKey={sortKey} sortDir={sortDir} onSort={toggle} style={TASK_TABLE_TH_STYLE}>Name</SortTh>
                    <SortTh col="project"     sortKey={sortKey} sortDir={sortDir} onSort={toggle} style={TASK_TABLE_TH_STYLE}>Project</SortTh>
                    <SortTh col="assigned"     sortKey={sortKey} sortDir={sortDir} onSort={toggle} style={{ ...TASK_TABLE_TH_STYLE, textAlign: 'center' }}>Assigned</SortTh>
                    <SortTh col="priority"     sortKey={sortKey} sortDir={sortDir} onSort={toggle} style={{ ...TASK_TABLE_TH_STYLE, textAlign: 'center' }}>Priority</SortTh>
                    <SortTh col="serviceType" sortKey={sortKey} sortDir={sortDir} onSort={toggle} style={{ ...TASK_TABLE_TH_STYLE, textAlign: 'center' }}>Task Type</SortTh>
                    <SortTh col="deadline"    sortKey={sortKey} sortDir={sortDir} onSort={toggle} style={{ ...TASK_TABLE_TH_STYLE, textAlign: 'center' }}>Deadline</SortTh>
                  </tr>
                </thead>
                <tbody>{sortedRows.map(renderRow)}</tbody>
              </table>
            </div>
          )}
        </div>
        {error && <div style={{ color: 'var(--danger)', marginTop: 16, fontSize: 13 }}>{error}</div>}
      </TasksPageShell>
      {uploadProgress.active && (
        <div style={{ ...popupOverlayStyle, zIndex: 1200 }}>
          <div style={{ background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 8, padding: '18px 21px', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)', width: '100%', maxWidth: 340, display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div style={{ fontSize: 11, fontWeight: 500, textTransform: 'uppercase', letterSpacing: 0.8, color: 'var(--text-secondary)' }}>Uploading</div>
            <div style={{ fontSize: 12, color: 'var(--text-secondary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{uploadProgress.label}</div>
            <div style={{ height: 4, borderRadius: 2, background: 'var(--card-bg-2)', overflow: 'hidden' }}>
              <div style={{ height: '100%', borderRadius: 2, background: 'var(--accent)', width: `${uploadProgress.percent}%`, transition: 'width 200ms ease' }} />
            </div>
            <div style={{ fontSize: 12, color: 'var(--text-muted)', textAlign: 'right' }}>{uploadProgress.percent}%</div>
          </div>
        </div>
      )}
    </Layout>
  );
}
