<script>
  import { getTasks, addTask, updateTask, deleteTask } from './api.js';
  import { formatRelativeDate, isOverdue } from './utils.js';
  import UserManager from './UserManager.svelte';

  let selectedUserId = $state(null);
  let tasks = $state([]);
  let error = $state('');

  // Period and day-of-week labels
  const PERIODS = ['Morning', 'Afternoon', 'Evening'];
  const PERIOD_ICONS = ['🌅', '☀️', '🌙'];
  const DAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];

  // Shared bitmask helpers (used for both period and recurrence)
  function toggleBit(current, idx) {
    return current ^ (1 << idx);
  }

  function hasBit(mask, idx) {
    return (mask & (1 << idx)) !== 0;
  }

  function formatPeriod(mask) {
    if (mask === 0x07) return 'All Day';
    const names = [];
    for (let i = 0; i < 3; i++) {
      if (mask & (1 << i)) names.push(PERIODS[i]);
    }
    return names.length > 0 ? names.join(', ') : 'None';
  }

  function periodIcons(mask) {
    const icons = [];
    for (let i = 0; i < 3; i++) {
      if (mask & (1 << i)) icons.push(PERIOD_ICONS[i]);
    }
    return icons.join('');
  }

  function formatRecurrence(mask) {
    if (mask === 0x7F) return 'Every day';
    if (mask === 0x1F) return 'Weekdays';
    if (mask === 0x60) return 'Weekends';
    const names = [];
    for (let i = 0; i < 7; i++) {
      if (mask & (1 << i)) names.push(DAYS[i]);
    }
    return names.join(', ');
  }

  // Add task form state
  let newTitle = $state('');
  let newPeriod = $state(0x01);
  let newRecurrence = $state(0);
  let newDueDay = $state('');
  let showAddForm = $state(false);

  // Edit state
  let editingTaskId = $state(null);
  let editTitle = $state('');
  let editPeriod = $state(0);
  let editRecurrence = $state(0);
  let editDueDay = $state('');

  // Confirm delete
  let confirmDeleteId = $state(null);

  async function fetchTasks() {
    if (!selectedUserId) {
      tasks = [];
      return;
    }
    try {
      tasks = await getTasks(selectedUserId);
      // Sort: recurrent first (by day), then one-off by due_date
      tasks.sort((a, b) => {
        if (a.recurrence && !b.recurrence) return -1;
        if (!a.recurrence && b.recurrence) return 1;
        if (a.recurrence && b.recurrence) return a.recurrence - b.recurrence;
        return a.due_date - b.due_date;
      });
      error = '';
    } catch (e) {
      error = e.message;
    }
  }

  // Refetch when selected user changes
  $effect(() => {
    if (selectedUserId) {
      fetchTasks();
    } else {
      tasks = [];
    }
  });

  async function handleAddTask(e) {
    e.preventDefault();
    if (!newTitle.trim()) return;
    if (newRecurrence === 0 && !newDueDay) return;

    const dueTimestamp = newRecurrence > 0
      ? 0
      : Math.floor(new Date(`${newDueDay}T00:00`).getTime() / 1000);

    try {
      await addTask(selectedUserId, newTitle.trim(), dueTimestamp, newPeriod, newRecurrence);
      newTitle = '';
      newPeriod = 0x01;
      newRecurrence = 0;
      newDueDay = '';
      showAddForm = false;
      await fetchTasks();
    } catch (e) {
      error = e.message;
    }
  }

  async function handleToggleComplete(task) {
    try {
      await updateTask(task.id, { completed: !task.completed });
      await fetchTasks();
    } catch (e) {
      error = e.message;
    }
  }

  function startEditing(task) {
    editingTaskId = task.id;
    editTitle = task.title;
    editPeriod = task.period;
    editRecurrence = task.recurrence;
    if (task.recurrence === 0 && task.due_date) {
      const d = new Date(task.due_date * 1000);
      const year = d.getFullYear();
      const month = String(d.getMonth() + 1).padStart(2, '0');
      const dayNum = String(d.getDate()).padStart(2, '0');
      editDueDay = `${year}-${month}-${dayNum}`;
    } else {
      editDueDay = '';
    }
  }

  async function saveEdit(e) {
    e.preventDefault();
    if (!editTitle.trim()) return;
    if (editRecurrence === 0 && !editDueDay) return;

    const dueTimestamp = editRecurrence > 0
      ? 0
      : Math.floor(new Date(`${editDueDay}T00:00`).getTime() / 1000);

    try {
      await updateTask(editingTaskId, {
        title: editTitle.trim(),
        due_date: dueTimestamp,
        period: editPeriod,
        recurrence: editRecurrence
      });
      editingTaskId = null;
      await fetchTasks();
    } catch (e) {
      error = e.message;
    }
  }

  async function handleDelete(id) {
    try {
      await deleteTask(id);
      confirmDeleteId = null;
      await fetchTasks();
    } catch (e) {
      error = e.message;
    }
  }

  function setTodayForNewTask() {
    const d = new Date();
    const year = d.getFullYear();
    const month = String(d.getMonth() + 1).padStart(2, '0');
    const dayNum = String(d.getDate()).padStart(2, '0');
    newDueDay = `${year}-${month}-${dayNum}`;
  }

  function taskIsOverdue(task) {
    if (task.recurrence > 0) return false;
    return isOverdue(task.due_date);
  }
</script>

<div class="w-full">
  <UserManager bind:selectedUserId onUsersChanged={fetchTasks} />

  {#if selectedUserId}
    <div class="flex items-center justify-between mb-3">
      <h2 class="text-sm font-semibold uppercase tracking-[0.05em] text-text-primary">Tasks</h2>
      {#if !showAddForm}
        <button
          class="px-3.5 py-1.5 rounded-lg border border-accent bg-accent/10 text-accent cursor-pointer text-xs font-semibold transition-all hover:bg-accent/20"
          onclick={() => { showAddForm = true; setTodayForNewTask(); }}
        >+ Add Task</button>
      {/if}
    </div>

    {#if showAddForm}
      <form class="flex flex-col gap-2 p-3 rounded-[10px] border border-border bg-bg-card mb-3" onsubmit={handleAddTask}>
        <!-- svelte-ignore a11y_autofocus -->
        <input
          type="text"
          bind:value={newTitle}
          placeholder="Task title..."
          class="px-3 py-2 rounded-lg border border-border bg-bg-primary text-text-primary text-[13px] outline-none w-full box-border focus:border-accent"
          autofocus
        />

        <div class="flex gap-2">
          <div class="flex flex-col gap-1 flex-1">
            <span class="text-[10px] font-semibold uppercase tracking-[0.05em] text-text-secondary">Period</span>
            <div class="flex gap-1">
              {#each PERIODS as p, i}
                <button
                  type="button"
                  class="flex-1 px-2 py-1.5 rounded-md border cursor-pointer text-[11px] transition-all whitespace-nowrap
                    {hasBit(newPeriod, i)
                      ? 'border-accent bg-accent/15 text-accent font-semibold'
                      : 'border-border bg-bg-primary text-text-secondary hover:bg-bg-card-hover'}"
                  onclick={() => newPeriod = toggleBit(newPeriod, i)}
                >{PERIOD_ICONS[i]} {p}</button>
              {/each}
            </div>
          </div>
        </div>

        <div class="flex gap-2">
          <div class="flex flex-col gap-1 flex-1">
            <span class="text-[10px] font-semibold uppercase tracking-[0.05em] text-text-secondary">Recurrence</span>
            <div class="flex gap-[3px] flex-wrap">
              {#each DAYS as day, i}
                <button
                  type="button"
                  class="px-2 py-[5px] rounded-md border cursor-pointer text-[11px] transition-all min-w-8 text-center
                    {hasBit(newRecurrence, i)
                      ? 'border-accent bg-accent/15 text-accent font-semibold'
                      : 'border-border bg-bg-primary text-text-secondary hover:bg-bg-card-hover'}"
                  onclick={() => newRecurrence = toggleBit(newRecurrence, i)}
                >{day}</button>
              {/each}
            </div>
          </div>
        </div>

        {#if newRecurrence === 0}
          <div class="flex gap-2">
            <label class="flex flex-col gap-1 flex-1">
              <span class="text-[10px] font-semibold uppercase tracking-[0.05em] text-text-secondary">Date</span>
              <input type="date" bind:value={newDueDay}
                class="date-input px-3 py-2 rounded-lg border border-border bg-bg-primary text-text-primary text-[13px] outline-none [color-scheme:dark] flex-1 cursor-pointer relative focus:border-accent" />
            </label>
          </div>
        {/if}

        <div class="flex gap-1.5">
          <button type="submit"
            class="px-4 py-1.5 rounded-lg border-none bg-accent text-white cursor-pointer text-xs font-semibold transition-[filter] hover:brightness-110 disabled:opacity-40 disabled:cursor-not-allowed"
            disabled={!newTitle.trim() || (newRecurrence === 0 && !newDueDay)}>Add</button>
          <button type="button"
            class="px-4 py-1.5 rounded-lg border border-border bg-transparent text-text-secondary cursor-pointer text-xs transition-all hover:bg-bg-card-hover"
            onclick={() => { showAddForm = false; newTitle = ''; newDueDay = ''; newRecurrence = 0; newPeriod = 0x01; }}>Cancel</button>
        </div>
      </form>
    {/if}

    <div class="flex flex-col gap-1">
      {#each tasks as task}
        <div class="flex items-center justify-between flex-wrap px-3.5 py-2.5 rounded-[10px] border bg-bg-card transition-all hover:bg-bg-card-hover
          {task.completed ? 'opacity-50' : ''}
          {taskIsOverdue(task) && !task.completed ? 'border-danger/40' : 'border-border'}">
          {#if editingTaskId === task.id}
            <form class="w-full flex flex-col gap-2 p-0" onsubmit={saveEdit}>
              <input type="text" bind:value={editTitle}
                class="px-3 py-2 rounded-lg border border-border bg-bg-primary text-text-primary text-[13px] outline-none w-full box-border focus:border-accent" />

              <div class="flex gap-2">
                <div class="flex flex-col gap-1 flex-1">
                  <span class="text-[10px] font-semibold uppercase tracking-[0.05em] text-text-secondary">Period</span>
                  <div class="flex gap-1">
                    {#each PERIODS as p, i}
                      <button type="button"
                        class="flex-1 px-2 py-1.5 rounded-md border cursor-pointer text-[11px] transition-all whitespace-nowrap
                          {hasBit(editPeriod, i)
                            ? 'border-accent bg-accent/15 text-accent font-semibold'
                            : 'border-border bg-bg-primary text-text-secondary hover:bg-bg-card-hover'}"
                        onclick={() => editPeriod = toggleBit(editPeriod, i)}
                      >{PERIOD_ICONS[i]} {p}</button>
                    {/each}
                  </div>
                </div>
              </div>

              <div class="flex gap-2">
                <div class="flex flex-col gap-1 flex-1">
                  <span class="text-[10px] font-semibold uppercase tracking-[0.05em] text-text-secondary">Recurrence</span>
                  <div class="flex gap-[3px] flex-wrap">
                    {#each DAYS as day, i}
                      <button type="button"
                        class="px-2 py-[5px] rounded-md border cursor-pointer text-[11px] transition-all min-w-8 text-center
                          {hasBit(editRecurrence, i)
                            ? 'border-accent bg-accent/15 text-accent font-semibold'
                            : 'border-border bg-bg-primary text-text-secondary hover:bg-bg-card-hover'}"
                        onclick={() => editRecurrence = toggleBit(editRecurrence, i)}
                      >{day}</button>
                    {/each}
                  </div>
                </div>
              </div>

              {#if editRecurrence === 0}
                <div class="flex gap-2">
                  <label class="flex flex-col gap-1 flex-1">
                    <span class="text-[10px] font-semibold uppercase tracking-[0.05em] text-text-secondary">Date</span>
                    <input type="date" bind:value={editDueDay}
                      class="date-input px-3 py-2 rounded-lg border border-border bg-bg-primary text-text-primary text-[13px] outline-none [color-scheme:dark] flex-1 cursor-pointer relative focus:border-accent" />
                  </label>
                </div>
              {/if}

              <div class="flex gap-1.5">
                <button type="submit"
                  class="px-2.5 py-1 rounded-lg border-none bg-accent text-white cursor-pointer text-[11px] font-semibold transition-[filter] hover:brightness-110">Save</button>
                <button type="button"
                  class="px-2.5 py-1 rounded-lg border border-border bg-transparent text-text-secondary cursor-pointer text-[11px] transition-all hover:bg-bg-card-hover"
                  onclick={() => editingTaskId = null}>Cancel</button>
              </div>
            </form>
          {:else}
            <div class="flex items-center gap-2.5 flex-1 min-w-0">
              <input
                type="checkbox"
                checked={task.completed}
                onchange={() => handleToggleComplete(task)}
                class="w-4 h-4 cursor-pointer flex-shrink-0"
                style="accent-color: var(--color-accent)"
              />
              <div class="flex flex-col gap-0.5 min-w-0">
                <span class="text-[13px] text-text-primary whitespace-nowrap overflow-hidden text-ellipsis
                  {task.completed ? 'line-through text-text-secondary' : ''}">{task.title}</span>
                <div class="flex gap-2 items-center flex-wrap">
                  <span class="text-[10px] text-text-secondary font-medium">{periodIcons(task.period)} {formatPeriod(task.period)}</span>
                  {#if task.recurrence > 0}
                    <span class="text-[10px] text-accent font-medium">🔁 {formatRecurrence(task.recurrence)}</span>
                  {:else}
                    <span class="text-[10px] font-medium {taskIsOverdue(task) && !task.completed ? 'text-danger' : 'text-text-secondary'}">
                      {formatRelativeDate(task.due_date)}
                    </span>
                  {/if}
                </div>
              </div>
            </div>
            <div class="flex gap-1 items-center flex-shrink-0">
              <button class="bg-transparent border-none cursor-pointer text-xs p-1 rounded opacity-60 transition-[background] hover:opacity-100 hover:bg-bg-card-hover"
                onclick={() => startEditing(task)} title="Edit">✏️</button>
              {#if confirmDeleteId === task.id}
                <button class="bg-transparent border-none cursor-pointer text-xs p-1 rounded text-danger opacity-60 hover:opacity-100"
                  onclick={() => handleDelete(task.id)} title="Confirm">✓</button>
                <button class="bg-transparent border-none cursor-pointer text-xs p-1 rounded opacity-60 hover:opacity-100 hover:bg-bg-card-hover"
                  onclick={() => confirmDeleteId = null} title="Cancel">✕</button>
              {:else}
                <button class="bg-transparent border-none cursor-pointer text-xs p-1 rounded opacity-60 transition-[background] hover:opacity-100 hover:bg-bg-card-hover"
                  onclick={() => confirmDeleteId = task.id} title="Delete">🗑️</button>
              {/if}
            </div>
          {/if}
        </div>
      {:else}
        <div class="text-center p-8 text-text-secondary text-[13px]">No tasks yet. Add one above!</div>
      {/each}
    </div>
  {:else}
    <div class="text-center p-8 text-text-secondary text-[13px]">Select or add a user to see their tasks.</div>
  {/if}

  {#if error}
    <div class="mt-2 px-2.5 py-1.5 rounded-md bg-danger/10 border border-danger/20 text-danger text-[11px]">{error}</div>
  {/if}
</div>
