"use client";

import Link from "next/link";
import { useEffect, useMemo, useState } from "react";
import { displayJobItemError, isYouTubeUploadLimitError } from "@/lib/youtube/errors";
import type { JobResponse } from "@/lib/types";
import { YouTubeLimitBanner } from "./YouTubeLimitBanner";

const STATUS_LABELS: Record<string, string> = {
  PENDING: "Queued",
  ENCODING: "Encoding",
  UPLOADING: "Uploading",
  COMPLETED: "Completed",
  FAILED: "Failed",
};

function sameDay(a: Date, b: Date) {
  return (
    a.getFullYear() === b.getFullYear() &&
    a.getMonth() === b.getMonth() &&
    a.getDate() === b.getDate()
  );
}

function formatDayLabel(date: Date) {
  const today = new Date();
  const yesterday = new Date();
  yesterday.setDate(today.getDate() - 1);

  if (sameDay(date, today)) return "Today";
  if (sameDay(date, yesterday)) return "Yesterday";

  return date.toLocaleDateString(undefined, {
    weekday: "long",
    year: "numeric",
    month: "long",
    day: "numeric",
  });
}

function groupJobsByDay(jobs: JobResponse[]) {
  const groups = new Map<string, { label: string; jobs: JobResponse[] }>();

  for (const job of jobs) {
    const date = new Date(job.createdAt);
    const key = date.toLocaleDateString("en-CA");
    const existing = groups.get(key);

    if (existing) {
      existing.jobs.push(job);
    } else {
      groups.set(key, { label: formatDayLabel(date), jobs: [job] });
    }
  }

  return Array.from(groups.entries())
    .sort(([a], [b]) => b.localeCompare(a))
    .map(([, group]) => group);
}

function statusClass(status: string) {
  if (status === "COMPLETED") return "bg-green-500/20 text-green-400";
  if (status === "FAILED") return "bg-red-500/20 text-red-400";
  return "bg-yellow-500/20 text-yellow-400";
}

export function JobHistory() {
  const [jobs, setJobs] = useState<JobResponse[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let active = true;

    async function load() {
      try {
        const res = await fetch("/api/jobs?limit=100");
        if (!res.ok) throw new Error("Failed to load history");
        const data = await res.json();
        if (active) setJobs(data.jobs);
      } catch (err) {
        if (active) setError(err instanceof Error ? err.message : "Error loading history");
      } finally {
        if (active) setLoading(false);
      }
    }

    load();
    return () => {
      active = false;
    };
  }, []);

  const dayGroups = useMemo(() => groupJobsByDay(jobs), [jobs]);
  const youtubeLimitHit = useMemo(
    () =>
      jobs.some((job) =>
        job.items.some(
          (item) => item.status === "FAILED" && item.error && isYouTubeUploadLimitError(item.error),
        ),
      ),
    [jobs],
  );

  if (loading) {
    return <div className="text-gray-400">Loading history…</div>;
  }

  if (error) {
    return (
      <div className="rounded border border-red-500/50 bg-red-500/10 p-4 text-red-300">{error}</div>
    );
  }

  if (dayGroups.length === 0) {
    return (
      <div className="rounded-lg border border-gray-700 bg-surface-light p-8 text-center">
        <p className="text-gray-400">No videos created yet.</p>
        <Link
          href="/dashboard"
          className="mt-4 inline-block rounded bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover"
        >
          Create your first video
        </Link>
      </div>
    );
  }

  return (
    <div className="space-y-8">
      {youtubeLimitHit && <YouTubeLimitBanner />}

      {dayGroups.map((group) => (
        <section key={group.label}>
          <h2 className="mb-4 text-lg font-semibold text-white">{group.label}</h2>

          <div className="space-y-4">
            {group.jobs.map((job) => (
              <div
                key={job.id}
                className="rounded-lg border border-gray-700 bg-surface-light p-4"
              >
                <div className="mb-3 flex items-center justify-between gap-4">
                  <div>
                    <p className="text-sm text-gray-400">
                      {new Date(job.createdAt).toLocaleTimeString(undefined, {
                        hour: "2-digit",
                        minute: "2-digit",
                      })}
                      {" · "}
                      {job.items.length} video{job.items.length === 1 ? "" : "s"}
                    </p>
                    <p className="text-xs text-gray-500">
                      Status: <span className="text-gray-300">{job.status}</span>
                    </p>
                  </div>
                  <Link
                    href={`/jobs/${job.id}`}
                    className="text-sm text-accent transition-colors hover:text-accent-hover"
                  >
                    View job
                  </Link>
                </div>

                <div className="space-y-2">
                  {job.items.map((item) => {
                    const itemError =
                      item.status === "FAILED" ? displayJobItemError(item.error) : null;

                    return (
                      <div
                        key={item.id}
                        className="rounded border border-gray-800 bg-surface px-3 py-2"
                      >
                        <div className="flex items-start justify-between gap-4">
                          <div className="min-w-0">
                            <p className="truncate font-medium text-white">{item.title}</p>
                            <p className="truncate text-xs text-gray-500">{item.audioFilename}</p>
                            {item.youtubeVideoId && (
                              <a
                                href={`https://youtube.com/watch?v=${item.youtubeVideoId}`}
                                target="_blank"
                                rel="noopener noreferrer"
                                className="mt-1 inline-block text-xs text-accent hover:underline"
                              >
                                View on YouTube
                              </a>
                            )}
                          </div>
                          <span
                            className={`shrink-0 rounded px-2 py-1 text-xs font-medium ${statusClass(item.status)}`}
                          >
                            {STATUS_LABELS[item.status] || item.status}
                          </span>
                        </div>
                        {itemError && (
                          <p className="mt-2 text-xs leading-relaxed text-red-400">{itemError}</p>
                        )}
                      </div>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>
        </section>
      ))}
    </div>
  );
}
