// Projects.jsx — Full projects page (Fase 2.3)
const { useState: useProjState, useEffect: useProjEffect, useRef: useProjRef } = React;

// ── i18n ─────────────────────────────────────────────────────────
function getProjLang() { return localStorage.getItem('el-lang') || 'no'; }

const PROJ_I18N = {
  no: {
    loading: 'Laster prosjekter...',
    unnamed: '(Uten navn)',
    projectName: 'Prosjektnavn',
    dblClickEdit: 'Dobbeltklikk for å endre',
    removeFav: 'Fjern favoritt',
    addFav: 'Legg til favoritt',
    archive: 'Arkiver prosjekt',
    sectionTasks: 'Oppgaver',
    noTasks: 'Ingen oppgaver ennå',
    newTask: 'Ny oppgave…',
    addTask: 'Legg til oppgave',
    deleteTask: 'Slett oppgave',
    taskPlaceholder: 'Oppgave',
    title: 'Prosjekter',
    shownCount: n => `${n} prosjekter vist`,
    filterFavorites: 'Stjerner',
    filterActive: 'Aktive',
    filterCompleted: 'Fullførte',
    newProject: 'Nytt prosjekt',
    noProjects: 'Ingen prosjekter ennå',
    newProjectPrompt: 'Prosjektnavn:',
    moreTasks: n => `+ ${n} til…`,
    showLess: 'Vis færre',
    prevPage: 'Forrige',
    nextPage: 'Neste',
    pageOf: (p, t) => `${p}/${t}`,
  },
  en: {
    loading: 'Loading projects...',
    unnamed: '(No name)',
    projectName: 'Project name',
    dblClickEdit: 'Double-click to edit',
    removeFav: 'Remove favorite',
    addFav: 'Add to favorites',
    archive: 'Archive project',
    sectionTasks: 'Tasks',
    noTasks: 'No tasks yet',
    newTask: 'New task…',
    addTask: 'Add task',
    deleteTask: 'Delete task',
    taskPlaceholder: 'Task',
    title: 'Projects',
    shownCount: n => `${n} projects shown`,
    filterFavorites: 'Starred',
    filterActive: 'Active',
    filterCompleted: 'Completed',
    newProject: 'New project',
    noProjects: 'No projects yet',
    newProjectPrompt: 'Project name:',
    moreTasks: n => `+ ${n} more…`,
    showLess: 'Show less',
    prevPage: 'Previous',
    nextPage: 'Next',
    pageOf: (p, t) => `${p}/${t}`,
  },
};

function pt(lang) { return PROJ_I18N[lang] || PROJ_I18N.no; }

// Number of tasks visible per page in both Easy and Pro modes
const PROJ_TASK_PAGE = 5;

function projDemo() {
  return window.EASYLIFE_DEMO?.enabled ? window.EASYLIFE_DEMO : null;
}

function ProgressRing({ done, total, size = 44, strokeWidth = 3 }) {
  const R = (size - strokeWidth * 2) / 2;
  const circ = 2 * Math.PI * R;
  const pct = total > 0 ? done / total : 0;
  const offset = circ * (1 - pct);

  return (
    <div className="pc-ring">
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <circle cx={size/2} cy={size/2} r={R} className="pc-ring-bg" strokeWidth={strokeWidth} />
        <circle
          cx={size/2} cy={size/2} r={R}
          className="pc-ring-fg"
          strokeWidth={strokeWidth}
          strokeDasharray={circ}
          strokeDashoffset={offset}
        />
      </svg>
      <div className="pc-ring-text">
        {total > 0 ? Math.round(pct * 100) : 0}%
      </div>
    </div>
  );
}

function ProjInlineEdit({ value, onSave, className, style, placeholder, editTitle }) {
  const [editing, setProjEditState] = useProjState(false);
  const [val, setVal] = useProjState(value || '');
  const inputRef = useProjRef(null);

  useProjEffect(() => { if (editing && inputRef.current) inputRef.current.focus(); }, [editing]);

  function commit() {
    const trimmed = val.trim();
    if (trimmed && trimmed !== value) onSave(trimmed);
    setProjEditState(false);
  }

  if (editing) {
    return (
      <input
        ref={inputRef}
        value={val}
        onChange={e => setVal(e.target.value)}
        className={className}
        style={{ ...style, background: 'transparent', border: 'none', borderBottom: '1px solid var(--accent-bd)', outline: 'none', fontFamily: 'var(--font)', padding: '0 2px' }}
        placeholder={placeholder}
        onBlur={commit}
        onKeyDown={e => { if (e.key === 'Enter') commit(); if (e.key === 'Escape') { setVal(value || ''); setProjEditState(false); } }}
      />
    );
  }
  return (
    <span className={className} style={{ ...style, cursor: 'text' }} title={editTitle || 'Double-click to edit'} onDoubleClick={() => { setVal(value || ''); setProjEditState(true); }}>
      {value || placeholder || ''}
    </span>
  );
}

function ProjectCard({ project, tasks, uiMode, onToggleTask, onToggleFav, onAddTask, onRenameProject, onRenameTask, onDeleteTask, onArchive, deadlineInfo, T }) {
  const [adding, setAdding] = useProjState(false);
  const [newTask, setNewTask] = useProjState('');
  const [taskPage, setTaskPage] = useProjState(0);
  const inputRef = useProjRef(null);
  const projectTasks = tasks.filter(t => t.project_id === project.id);
  // Sort: uncompleted first, then completed (stable within each group)
  const sortedTasks = [...projectTasks].sort((a, b) => (a.completed ? 1 : 0) - (b.completed ? 1 : 0));
  const doneTasks = projectTasks.filter(t => t.completed);
  const isFav = project.is_favorite || project.hot;
  const isEasy = uiMode === 'easy';

  // Pagination (same for both easy and pro modes)
  const totalPages = Math.ceil(sortedTasks.length / PROJ_TASK_PAGE);
  const safePage = Math.min(taskPage, Math.max(0, totalPages - 1));
  const visibleTasks = sortedTasks.slice(safePage * PROJ_TASK_PAGE, (safePage + 1) * PROJ_TASK_PAGE);
  const showPagination = sortedTasks.length > PROJ_TASK_PAGE;

  useProjEffect(() => {
    if (adding && inputRef.current) inputRef.current.focus();
  }, [adding]);

  async function submitTask(e) {
    e.preventDefault();
    if (!newTask.trim()) return;
    await onAddTask(project.id, newTask.trim());
    setNewTask('');
    setAdding(false);
  }

  return (
    <div className={`pc${isFav ? ' fav' : ''}${isEasy ? ' pc-easy' : ''}`}>
      {/* Favorite button — always visible */}
      <button
        className={`pc-fav${isFav ? ' active' : ''}`}
        onClick={() => onToggleFav(project.id, isFav)}
        title={isFav ? T.removeFav : T.addFav}
      >
        <i className={`ti ${isFav ? 'ti-star-filled' : 'ti-star'}`}></i>
      </button>

      {/* Archive button */}
      {onArchive && (
        <button
          className="pc-arc"
          onClick={() => onArchive(project.id)}
          title={T.archive}
        >
          <i className="ti ti-archive"></i>
        </button>
      )}

      {/* Progress ring — Pro only; Easy uses a flat bar inside the card */}
      {!isEasy && <ProgressRing done={doneTasks.length} total={projectTasks.length} />}

      {/* Header */}
      <div className="pc-head">
        <div className="pc-head-text">
          <ProjInlineEdit
            value={project.title || project.name || T.unnamed}
            onSave={v => onRenameProject && onRenameProject(project.id, v)}
            className="pc-title"
            style={{ display: 'block' }}
            placeholder={T.projectName}
            editTitle={T.dblClickEdit}
          />
          {/* Task count and deadline: Pro mode only */}
          {!isEasy && (
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap', marginTop: 2 }}>
              <span className="pc-sub">
                <i className="ti ti-list-check"></i>
                {doneTasks.length}/{projectTasks.length} {T.sectionTasks.toLowerCase()}
              </span>
              {deadlineInfo && (
                <span className={`pc-deadline-pill${deadlineInfo.overdue ? ' overdue' : deadlineInfo.soon ? ' soon' : ''}`}>
                  <i className="ti ti-clock"></i>
                  {deadlineInfo.label}
                </span>
              )}
            </div>
          )}
        </div>
      </div>

      {isEasy ? (
        <>
          {/* Progress bar — directly after title in easy mode */}
          <div className="pc-easy-bar" aria-hidden="true">
            <div
              className="pc-easy-bar-fill"
              style={{ width: `${projectTasks.length > 0 ? Math.round((doneTasks.length / projectTasks.length) * 100) : 0}%` }}
            />
          </div>

          {/* Task list for easy mode */}
          <div className="pc-tasks" style={{ marginTop: 10 }}>
            {visibleTasks.map(task => (
              <div key={task.id} className={`pc-task${task.completed ? ' done' : ''}`}>
                <button
                  className={`pc-task-check${task.completed ? ' chk' : ''}`}
                  onClick={() => onToggleTask(task.id, task.completed)}
                />
                <span className="pc-task-text">{task.title || task.name || task.text}</span>
              </div>
            ))}
            {sortedTasks.length === 0 && (
              <p style={{ fontSize: 12, color: 'var(--mut)', fontStyle: 'italic', padding: '4px 3px' }}>{T.noTasks}</p>
            )}
            {showPagination && (
              <div className="pc-pagination">
                <button
                  className="pc-page-btn"
                  disabled={safePage === 0}
                  onClick={() => setTaskPage(p => Math.max(0, p - 1))}
                >
                  <i className="ti ti-chevron-left"></i> {T.prevPage}
                </button>
                <span className="pc-page-info">{T.pageOf(safePage + 1, totalPages)}</span>
                <button
                  className="pc-page-btn"
                  disabled={safePage >= totalPages - 1}
                  onClick={() => setTaskPage(p => Math.min(totalPages - 1, p + 1))}
                >
                  {T.nextPage} <i className="ti ti-chevron-right"></i>
                </button>
              </div>
            )}
          </div>

          {/* Add task — easy mode */}
          {adding ? (
            <form onSubmit={submitTask} className="pc-add is-adding">
              <i className="ti ti-plus pc-add-icon"></i>
              <input
                ref={inputRef}
                value={newTask}
                onChange={e => setNewTask(e.target.value)}
                placeholder={T.newTask}
                onBlur={() => { if (!newTask.trim()) setAdding(false); }}
              />
              {newTask.trim() && (
                <button type="submit" className="pc-add-submit">
                  <i className="ti ti-arrow-right"></i>
                </button>
              )}
            </form>
          ) : (
            <button className="pc-add" onClick={() => setAdding(true)}>
              <i className="ti ti-plus pc-add-icon"></i>
              <span className="pc-add-text">{T.addTask}</span>
            </button>
          )}
        </>
      ) : (
        <>
          <hr className="pc-divider" />

          {/* Tasks */}
          <div className="pc-section-label">{T.sectionTasks}</div>
          <div className="pc-tasks">
            {visibleTasks.map(task => (
              <div key={task.id} className={`pc-task${task.completed ? ' done' : ''}`}>
                <button
                  className={`pc-task-check${task.completed ? ' chk' : ''}`}
                  onClick={() => onToggleTask(task.id, task.completed)}
                />
                <ProjInlineEdit
                  value={task.title || task.name || task.text}
                  onSave={v => onRenameTask && onRenameTask(task.id, v)}
                  className="pc-task-text"
                  placeholder={T.taskPlaceholder}
                  editTitle={T.dblClickEdit}
                />
                <button
                  className="pc-task-del"
                  title={T.deleteTask}
                  onClick={e => { e.stopPropagation(); onDeleteTask && onDeleteTask(task.id); }}
                >
                  <i className="ti ti-x"></i>
                </button>
              </div>
            ))}
            {sortedTasks.length === 0 && (
              <p style={{ fontSize: 12, color: 'var(--mut)', fontStyle: 'italic', padding: '4px 3px' }}>{T.noTasks}</p>
            )}
            {showPagination && (
              <div className="pc-pagination">
                <button
                  className="pc-page-btn"
                  disabled={safePage === 0}
                  onClick={() => setTaskPage(p => Math.max(0, p - 1))}
                >
                  <i className="ti ti-chevron-left"></i> {T.prevPage}
                </button>
                <span className="pc-page-info">{T.pageOf(safePage + 1, totalPages)}</span>
                <button
                  className="pc-page-btn"
                  disabled={safePage >= totalPages - 1}
                  onClick={() => setTaskPage(p => Math.min(totalPages - 1, p + 1))}
                >
                  {T.nextPage} <i className="ti ti-chevron-right"></i>
                </button>
              </div>
            )}
          </div>

          {/* Add task */}
          {adding ? (
            <form onSubmit={submitTask} className="pc-add is-adding">
              <i className="ti ti-plus pc-add-icon"></i>
              <input
                ref={inputRef}
                value={newTask}
                onChange={e => setNewTask(e.target.value)}
                placeholder={T.newTask}
                onBlur={() => { if (!newTask.trim()) setAdding(false); }}
              />
              {newTask.trim() && (
                <button type="submit" className="pc-add-submit">
                  <i className="ti ti-arrow-right"></i>
                </button>
              )}
            </form>
          ) : (
            <button className="pc-add" onClick={() => setAdding(true)}>
              <i className="ti ti-plus pc-add-icon"></i>
              <span className="pc-add-text">{T.addTask}</span>
            </button>
          )}
        </>
      )}
    </div>
  );
}

function Projects({ uiMode }) {
  const [projects, setProjects] = useProjState([]);
  const [tasks, setTasks] = useProjState([]);
  const [loading, setLoading] = useProjState(true);
  const [filterTab, setFilterTab] = useProjState('favorites'); // 'favorites' | 'active' | 'completed'
  const [projectDeadlines, setProjectDeadlines] = useProjState([]);
  const [wpFilter] = useWpFilter(); // Global Work / Personal filter from topnav
  const [lang, setLang] = useProjState(() => getProjLang());

  useProjEffect(() => {
    const handler = e => setLang(e.detail || getProjLang());
    window.addEventListener('el-lang-change', handler);
    return () => window.removeEventListener('el-lang-change', handler);
  }, []);

  const T = pt(lang);

  useProjEffect(() => {
    loadData();
  }, []);

  async function loadData() {
    setLoading(true);
    try {
      const { data: projData } = await supabaseClient
        .from('projects')
        .select('id, name, summary, favorite, status, work_personal_category, tag_id, archived_at, created_at, updated_at')
        .is('archived_at', null)
        .order('created_at', { ascending: false });

      const mappedProj = (projData || []).map(p => ({
        ...p,
        title: p.name,
        is_favorite: p.favorite,
        hot: p.favorite,
      }));
      setProjects(mappedProj.length ? mappedProj : (projDemo()?.projects || []));

      // Project tasks live in project_todos (per V2/SUPABASE.md §5)
      const projectIds = mappedProj.map(p => p.id);
      let taskData = null;
      if (projectIds.length > 0) {
        const res = await supabaseClient
          .from('project_todos')
          .select('id, project_id, name, completed, completed_at, position, due_date')
          .in('project_id', projectIds)
          .order('position', { ascending: true });
        taskData = res.data;
      }
      const mappedTasks = (taskData || []).map(t => ({ ...t, title: t.name }));
      setTasks(mappedTasks.length ? mappedTasks : (projDemo()?.tasks || []));

      // Project deadlines
      if (projectIds.length > 0) {
        try {
          const { data: dlData } = await supabaseClient
            .from('project_deadlines')
            .select('id, project_id, title, due_date')
            .in('project_id', projectIds)
            .order('due_date', { ascending: true });
          setProjectDeadlines(dlData || []);
        } catch (_) { /* table may not exist yet */ }
      }
    } catch (e) {
      const demo = projDemo();
      if (demo) {
        setProjects(demo.projects);
        setTasks(demo.tasks);
      }
    } finally {
      setLoading(false);
    }
  }

  async function toggleTask(id, completed) {
    const newCompleted = !completed;
    const newCompletedAt = newCompleted ? new Date().toISOString() : null;
    setTasks(prev => prev.map(t => t.id === id ? { ...t, completed: newCompleted, completed_at: newCompletedAt } : t));
    if (!projDemo()) {
      await supabaseClient
        .from('project_todos')
        .update({ completed: newCompleted, completed_at: newCompletedAt })
        .eq('id', id);
    }
  }

  async function toggleFav(projectId, isFav) {
    const newFav = !isFav;
    setProjects(prev => prev.map(p => p.id === projectId ? { ...p, favorite: newFav, is_favorite: newFav, hot: newFav } : p));
    if (!projDemo()) await supabaseClient.from('projects').update({ favorite: newFav }).eq('id', projectId);
  }

  async function addTask(projectId, title) {
    if (projDemo()) {
      setTasks(prev => [{ id: `demo-project-task-${Date.now()}`, title, name: title, project_id: projectId, completed: false, completed_at: null }, ...prev]);
      return;
    }
    const { data } = await supabaseClient
      .from('project_todos')
      .insert({ project_id: projectId, name: title, completed: false, position: Date.now() })
      .select()
      .single();
    if (data) {
      setTasks(prev => [{ ...data, title: data.name }, ...prev]);
    }
  }

  async function renameProject(projectId, newTitle) {
    setProjects(prev => prev.map(p => p.id === projectId ? { ...p, name: newTitle, title: newTitle } : p));
    if (!projDemo()) await supabaseClient.from('projects').update({ name: newTitle }).eq('id', projectId);
  }

  async function renameTask(taskId, newName) {
    setTasks(prev => prev.map(t => t.id === taskId ? { ...t, name: newName, title: newName } : t));
    if (!projDemo()) await supabaseClient.from('project_todos').update({ name: newName }).eq('id', taskId);
  }

  async function deleteProjectTask(taskId) {
    setTasks(prev => prev.filter(t => t.id !== taskId));
    if (!projDemo()) await supabaseClient.from('project_todos').delete().eq('id', taskId);
  }

  async function archiveProject(projectId) {
    setProjects(prev => prev.filter(p => p.id !== projectId));
    if (!projDemo()) {
      await supabaseClient.from('projects').update({ archived_at: new Date().toISOString() }).eq('id', projectId);
    }
  }

  async function createProject() {
    const title = prompt(T.newProjectPrompt);
    if (!title?.trim()) return;
    if (projDemo()) {
      setProjects(prev => [{ id: `demo-project-${Date.now()}`, title: title.trim(), name: title.trim(), is_favorite: false }, ...prev]);
      return;
    }
    const uid = await window.ensureCurrentUserId();
    if (!uid) return;
    const { data } = await supabaseClient
      .from('projects')
      .insert({ user_id: uid, name: title.trim() })
      .select()
      .single();
    if (data) {
      setProjects(prev => [{ ...data, title: data.name, is_favorite: data.favorite, hot: data.favorite }, ...prev]);
    }
  }

  // Filter projects + sort favorites first.
  // When 'favorites' is active but no favorites exist, fall back to showing all active projects.
  const filteredProjects = React.useMemo(() => {
    const wpKey = wpFilter.toLowerCase(); // 'work' or 'personal' (from topnav)
    const hasFavorites = projects.some(p => p.is_favorite || p.hot || p.favorite);
    const effectiveTab = (filterTab === 'favorites' && !hasFavorites) ? 'active' : filterTab;
    const filtered = projects.filter(p => {
      // Work / Personal filter: projects with no category ('' or 'none') always show;
      // projects with an explicit category only show when it matches the active filter.
      const cat = (p.work_personal_category || '').toLowerCase();
      if (cat && cat !== 'none' && cat !== wpKey) return false;
      // Favorites filter
      if (effectiveTab === 'favorites') return !!(p.is_favorite || p.hot || p.favorite);
      // Active / completed filter
      const ptasks = tasks.filter(t => t.project_id === p.id);
      const done = ptasks.filter(t => t.completed);
      const isCompleted = ptasks.length > 0 && done.length === ptasks.length;
      if (effectiveTab === 'active') return !isCompleted;
      if (effectiveTab === 'completed') return isCompleted;
      return true;
    });
    return filtered.sort((a, b) => {
      const aFav = a.is_favorite || a.hot || a.favorite ? 1 : 0;
      const bFav = b.is_favorite || b.hot || b.favorite ? 1 : 0;
      return bFav - aFav;
    });
  }, [projects, tasks, filterTab, wpFilter]);

  if (loading) {
    return (
      <div className="v2-page loading-spinner">
        <i className="ti ti-loader-2" style={{ animation: 'spin 1s linear infinite', fontSize: 20 }}></i>
        {T.loading}
        <style>{`@keyframes spin{to{transform:rotate(360deg)}}`}</style>
      </div>
    );
  }

  return (
    <div className="v2-page">
      {/* Page header */}
      <div className="pv-head">
        <div className="pv-head-left">
          <h2>{T.title}</h2>
          <p>{T.shownCount(filteredProjects.length)}</p>
        </div>
        <div className="pv-filters">
          <button
            className={`pf${filterTab === 'favorites' ? ' active' : ''}`}
            onClick={() => setFilterTab('favorites')}
            title={T.filterFavorites}
          >
            <i className="ti ti-star"></i>
            {T.filterFavorites}
          </button>
          {[
            { key: 'active', label: T.filterActive },
            { key: 'completed', label: T.filterCompleted },
          ].map(f => (
            <button
              key={f.key}
              className={`pf${filterTab === f.key ? ' active' : ''}`}
              onClick={() => setFilterTab(f.key)}
            >
              {f.label}
            </button>
          ))}
          <button className="pf new-pf" onClick={createProject}>
            <i className="ti ti-plus"></i>
            {T.newProject}
          </button>
        </div>
      </div>

      {/* Projects grid */}
      <div className="pv-grid">
        {filteredProjects.length === 0 ? (
          <div className="pv-empty">
            <i className="ti ti-layout-grid"></i>
            <p>{T.noProjects}</p>
          </div>
        ) : (
          <>
            {filteredProjects.map(project => {
              const dl = projectDeadlines.find(d => d.project_id === project.id);
              let deadlineInfo = null;
              if (dl?.due_date) {
                const due = new Date(dl.due_date);
                const diffDays = Math.ceil((due - new Date()) / (1000 * 60 * 60 * 24));
                deadlineInfo = {
                  label: diffDays < 0 ? `${Math.abs(diffDays)}d over` : diffDays === 0 ? 'I dag' : `om ${diffDays}d`,
                  overdue: diffDays < 0,
                  soon: diffDays >= 0 && diffDays <= 3,
                };
              }
              return (
                <ProjectCard
                  key={project.id}
                  project={project}
                  tasks={tasks}
                  uiMode={uiMode}
                  onToggleTask={toggleTask}
                  onToggleFav={toggleFav}
                  onAddTask={addTask}
                  onRenameProject={renameProject}
                  onRenameTask={renameTask}
                  onDeleteTask={deleteProjectTask}
                  onArchive={archiveProject}
                  deadlineInfo={deadlineInfo}
                  T={T}
                />
              );
            })}
            {/* New project card */}
            <div className="pc new-card" onClick={createProject}>
              <div style={{ textAlign: 'center' }}>
                <i className="ti ti-plus" style={{ fontSize: 28, color: 'var(--mut)', display: 'block', marginBottom: 8 }}></i>
                <span className="pc-new-text">{T.newProject}</span>
              </div>
            </div>
          </>
        )}
      </div>

      <style>{`@keyframes spin{to{transform:rotate(360deg)}}`}</style>
    </div>
  );
}
