import { useState, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { getDownloads, deleteDownload, deleteAllDownloads, restoreDownload, getActiveTasks } from "../api";
import SortPicker from "../components/SortPicker";

const HISTORY_SORTS = [
  { value: "newest", label: "Newest" },
  { value: "oldest", label: "Oldest" },
  { value: "title",  label: "Title A–Z" },
  { value: "status", label: "Status" },
];

function sortHistory(items, sort) {
  const arr = [...items];
  if (sort === "oldest") return arr.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
  if (sort === "title")  return arr.sort((a, b) => (a.video_title ?? "").localeCompare(b.video_title ?? ""));
  if (sort === "status") return arr.sort((a, b) => a.status.localeCompare(b.status));
  return arr.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
}

const STATUS_COLORS = {
  pending: "text-zinc-400",
  downloading: "text-accent",
  complete: "text-green-400",
  failed: "text-red-400",
};

const STATUS_LABELS = {
  pending: "Pending",
  downloading: "Downloading",
  complete: "Complete",
  failed: "Failed",
};

function ProgressBar({ pct }) {
  return (
    <div className="h-1 bg-zinc-800 rounded-full overflow-hidden mt-1.5">
      <div
        className="h-full bg-accent rounded-full transition-all duration-300"
        style={{ width: `${pct}%` }}
      />
    </div>
  );
}

function daysRemaining(pendingDeleteAt) {
  const diff = new Date(pendingDeleteAt) - Date.now();
  const days = Math.ceil(diff / (1000 * 60 * 60 * 24));
  return Math.max(0, days);
}

export default function DownloadsPage() {
  const [historySort, setHistorySort] = useState("newest");
  const [confirmClear, setConfirmClear] = useState(false);
  const qc = useQueryClient();

  const { data: downloads, isLoading } = useQuery({
    queryKey: ["downloads"],
    queryFn: () => getDownloads().then((r) => r.data),
    refetchInterval: (query) => {
      const active = query.state.data?.some(
        (d) => d.status === "pending" || d.status === "downloading"
      );
      return active ? 2000 : false;
    },
  });

  const { data: activeTasks = [] } = useQuery({
    queryKey: ["active-tasks"],
    queryFn: () => getActiveTasks().then((r) => r.data),
    refetchInterval: (query) => (query.state.data?.length > 0 ? 2000 : 5000),
  });

  const clearAllMut = useMutation({
    mutationFn: deleteAllDownloads,
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["downloads"] });
      setConfirmClear(false);
    },
  });

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-16">
        <div className="w-8 h-8 border-2 border-accent border-t-transparent rounded-full animate-spin" />
      </div>
    );
  }

  const active = downloads?.filter((d) => ["pending", "downloading"].includes(d.status)) ?? [];
  const trash = downloads?.filter((d) => d.pending_delete_at) ?? [];
  const history = useMemo(
    () => sortHistory(
      downloads?.filter((d) => !["pending", "downloading"].includes(d.status) && !d.pending_delete_at) ?? [],
      historySort,
    ),
    [downloads, historySort],
  );

  const hasRemovable = history.length > 0 || trash.length > 0;

  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center justify-between">
        <h1 className="font-display font-bold text-2xl text-zinc-100">Downloads</h1>
        {hasRemovable && (
          confirmClear ? (
            <div className="flex items-center gap-2">
              <span className="text-sm text-zinc-400">Remove all history and trash?</span>
              <button
                onClick={() => clearAllMut.mutate()}
                disabled={clearAllMut.isPending}
                className="px-3 py-1.5 rounded-lg bg-red-600 text-white text-sm font-medium hover:bg-red-500 disabled:opacity-50 transition-colors"
              >
                Yes, remove all
              </button>
              <button
                onClick={() => setConfirmClear(false)}
                className="px-3 py-1.5 rounded-lg bg-zinc-800 text-zinc-300 text-sm hover:bg-zinc-700 transition-colors"
              >
                Cancel
              </button>
            </div>
          ) : (
            <button
              onClick={() => setConfirmClear(true)}
              className="text-sm text-zinc-500 hover:text-red-400 transition-colors"
            >
              Remove all
            </button>
          )
        )}
      </div>

      {activeTasks.length > 0 && (
        <section>
          <h2 className="font-display font-semibold text-base text-zinc-400 mb-3">Background Tasks</h2>
          <div className="flex flex-col gap-3">
            {activeTasks.map((task) => {
              const pct = task.total > 0 ? (task.done / task.total) * 100 : 0;
              return (
                <div key={task.id} className="bg-zinc-900 rounded-xl p-4">
                  <p className="text-sm font-medium text-zinc-100 mb-0.5">{task.label}</p>
                  <div className="flex items-center justify-between mb-1">
                    <span className="text-xs text-zinc-400">{task.phase || "Running…"}</span>
                    {task.total > 0 && (
                      <span className="text-xs text-zinc-400 tabular-nums">{task.done}/{task.total}</span>
                    )}
                  </div>
                  <ProgressBar pct={pct} />
                </div>
              );
            })}
          </div>
        </section>
      )}

      {active.length > 0 && (
        <section>
          <h2 className="font-display font-semibold text-base text-zinc-400 mb-3">Active</h2>
          <div className="flex flex-col gap-3">
            {active.map((d) => (
              <DownloadRow key={d.id} download={d} />
            ))}
          </div>
        </section>
      )}

      {trash.length > 0 && (
        <section>
          <h2 className="font-display font-semibold text-base text-zinc-400 mb-1">Trash</h2>
          <p className="text-xs text-zinc-600 mb-3">Watched downloads — auto-deleted when the timer runs out.</p>
          <div className="flex flex-col gap-2">
            {trash.map((d) => (
              <TrashRow key={d.id} download={d} />
            ))}
          </div>
        </section>
      )}

      {history.length > 0 && (
        <section>
          <div className="flex items-center justify-between mb-3">
            <h2 className="font-display font-semibold text-base text-zinc-400">History</h2>
            <SortPicker value={historySort} onChange={setHistorySort} options={HISTORY_SORTS} />
          </div>
          <div className="flex flex-col gap-2">
            {history.map((d) => (
              <DownloadRow key={d.id} download={d} />
            ))}
          </div>
        </section>
      )}

      {!downloads?.length && (
        <p className="text-zinc-500 text-sm">No downloads yet. Find a video and hit Download.</p>
      )}
    </div>
  );
}

function TrashRow({ download: d }) {
  const navigate = useNavigate();
  const qc = useQueryClient();

  const restoreMut = useMutation({
    mutationFn: () => restoreDownload(d.id),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["downloads"] }),
  });

  const deleteMut = useMutation({
    mutationFn: () => deleteDownload(d.id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["downloads"] });
      qc.invalidateQueries({ queryKey: ["video-play", d.youtube_video_id] });
    },
  });

  const days = daysRemaining(d.pending_delete_at);
  const urgentColor = days <= 1 ? "text-red-400" : days <= 3 ? "text-amber-400" : "text-zinc-500";

  return (
    <div className="bg-zinc-900/60 border border-zinc-800 rounded-xl p-4 flex items-start gap-4">
      <div
        className="cursor-pointer shrink-0"
        onClick={() => navigate(`/watch/${d.youtube_video_id}`)}
      >
        {d.video_thumbnail_url ? (
          <img src={d.video_thumbnail_url} alt="" className="w-20 h-11 object-cover rounded-lg opacity-60" />
        ) : (
          <div className="w-20 h-11 rounded-lg bg-zinc-800" />
        )}
      </div>
      <div className="flex-1 min-w-0">
        <p
          className="text-sm font-medium text-zinc-400 truncate cursor-pointer hover:text-zinc-200 transition-colors"
          onClick={() => navigate(`/watch/${d.youtube_video_id}`)}
        >
          {d.video_title}
        </p>
        <p className={`text-xs mt-1 ${urgentColor}`}>
          {days === 0 ? "Deletes today" : `Deletes in ${days} day${days !== 1 ? "s" : ""}`}
        </p>
      </div>
      <div className="flex items-center gap-2 shrink-0">
        <button
          onClick={() => restoreMut.mutate()}
          disabled={restoreMut.isPending}
          title="Keep this file"
          className="px-2.5 py-1.5 rounded-lg text-xs font-medium text-zinc-300 bg-zinc-800 hover:bg-zinc-700 disabled:opacity-40 transition-colors"
        >
          Keep
        </button>
        <button
          onClick={() => deleteMut.mutate()}
          disabled={deleteMut.isPending}
          title="Delete now"
          className="p-1.5 rounded-lg text-zinc-600 hover:text-red-400 hover:bg-red-900/20 disabled:opacity-40 transition-colors"
        >
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
              d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
          </svg>
        </button>
      </div>
    </div>
  );
}

function DownloadRow({ download: d }) {
  const navigate = useNavigate();
  const qc = useQueryClient();
  const deleteMut = useMutation({
    mutationFn: () => deleteDownload(d.id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["downloads"] });
      qc.invalidateQueries({ queryKey: ["video-play", d.youtube_video_id] });
    },
  });

  const isActive = d.status === "pending" || d.status === "downloading";
  const canWatch = d.status === "complete" && d.youtube_video_id;

  return (
    <div className="bg-zinc-900 rounded-xl p-4 flex items-start gap-4">
      <div
        className={canWatch ? "cursor-pointer shrink-0" : "shrink-0"}
        onClick={canWatch ? () => navigate(`/watch/${d.youtube_video_id}`) : undefined}
      >
        {d.video_thumbnail_url ? (
          <img
            src={d.video_thumbnail_url}
            alt=""
            className="w-20 h-11 object-cover rounded-lg"
          />
        ) : (
          <div className="w-20 h-11 rounded-lg bg-zinc-800" />
        )}
      </div>
      <div className="flex-1 min-w-0">
        <p
          className={`text-sm font-medium text-zinc-100 truncate ${canWatch ? "cursor-pointer hover:text-white" : ""}`}
          onClick={canWatch ? () => navigate(`/watch/${d.youtube_video_id}`) : undefined}
        >
          {d.video_title}
        </p>
        <div className="flex items-center gap-2 mt-1">
          <span className={`text-xs font-medium ${STATUS_COLORS[d.status]}`}>
            {STATUS_LABELS[d.status]}
          </span>
          {d.status === "downloading" && (
            <span className="text-xs text-zinc-500">{d.progress_percent.toFixed(0)}%</span>
          )}
        </div>
        {d.status === "downloading" && <ProgressBar pct={d.progress_percent} />}
        {d.error_message && (
          <p className="text-xs text-red-400 mt-1 truncate">{d.error_message}</p>
        )}
      </div>
      <button
        onClick={() => deleteMut.mutate()}
        disabled={deleteMut.isPending}
        title={isActive ? "Cancel download" : "Delete file and record"}
        className="shrink-0 p-1.5 rounded-lg text-zinc-600 hover:text-red-400 hover:bg-red-900/20 transition-colors disabled:opacity-40"
      >
        {isActive ? (
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
          </svg>
        ) : (
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
              d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
          </svg>
        )}
      </button>
    </div>
  );
}
