"use client";

export const dynamic = "force-dynamic";

import { useMemo, useState, useEffect, useCallback } from "react";

import {
  type ColumnDef,
  getCoreRowModel,
  useReactTable,
} from "@tanstack/react-table";
import { AlertCircle, CheckCircle2, GitBranch, RefreshCw } from "lucide-react";

import Link from "next/link";

import { DashboardPageLayout } from "@/components/templates/DashboardPageLayout";
import { DataTable } from "@/components/tables/DataTable";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  getForgejoRepositories,
  type ForgejoRepository,
  syncRepository,
} from "@/lib/api-forgejo";

export default function GitProjectsPage() {
  const [repositories, setRepositories] = useState<ForgejoRepository[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [syncingId, setSyncingId] = useState<string | null>(null);
  const [syncResult, setSyncResult] = useState<{
    repoName: string;
    created: number;
    updated: number;
    open: number;
    closed: number;
    error?: string;
  } | null>(null);

  const fetchRepos = useCallback(async () => {
    try {
      const repos = await getForgejoRepositories();
      setRepositories(repos);
      setError(null);
    } catch (err) {
      setError(
        err instanceof Error
          ? err.message
          : "Pipeline could not load Git Projects.",
      );
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchRepos();
  }, [fetchRepos]);

  const handleSync = useCallback(
    async (repo: ForgejoRepository) => {
      setSyncingId(repo.id);
      setSyncResult(null);
      try {
        const result = await syncRepository(repo.id);
        setSyncResult({
          repoName: `${repo.owner}/${repo.repo}`,
          created: result.created,
          updated: result.updated,
          open: result.open,
          closed: result.closed,
        });
        await fetchRepos();
      } catch (err) {
        setSyncResult({
          repoName: `${repo.owner}/${repo.repo}`,
          created: 0,
          updated: 0,
          open: 0,
          closed: 0,
          error: err instanceof Error ? err.message : "Sync failed.",
        });
      } finally {
        setSyncingId(null);
      }
    },
    [fetchRepos],
  );

  const columns: ColumnDef<ForgejoRepository>[] = useMemo(
    () => [
      {
        accessorKey: "display_name",
        header: "Repository",
        cell: ({ row }) => {
          const repo = row.original;
          const name = repo.display_name || `${repo.owner}/${repo.repo}`;
          return (
            <div className="min-w-[180px]">
              <div className="truncate font-medium text-strong" title={name}>
                {name}
              </div>
              <div className="truncate font-mono text-xs text-muted">
                {repo.owner}/{repo.repo}
              </div>
            </div>
          );
        },
      },
      {
        accessorKey: "connection",
        header: "Connection",
        cell: ({ row }) => {
          const conn = row.original.connection;
          return (
            <span className="block max-w-[180px] truncate text-muted">
              {conn ? conn.name : "Unassigned"}
            </span>
          );
        },
      },
      {
        accessorKey: "active",
        header: "Status",
        cell: ({ row }) => (
          <Badge variant={row.original.active ? "success" : "outline"}>
            {row.original.active ? "Active" : "Inactive"}
          </Badge>
        ),
      },
      {
        accessorKey: "last_sync_at",
        header: "Last Synced",
        cell: ({ row }) => {
          const val = row.original.last_sync_at;
          if (!val) return <span className="text-muted">Never</span>;
          try {
            return (
              <span className="whitespace-nowrap text-muted">
                {new Date(val).toLocaleString()}
              </span>
            );
          } catch {
            return <span className="text-muted">{val}</span>;
          }
        },
      },
      {
        id: "actions",
        header: "",
        cell: ({ row }) => {
          const repo = row.original;
          const isSyncing = syncingId === repo.id;
          return (
            <Button
              variant="ghost"
              size="sm"
              className="whitespace-nowrap"
              onClick={() => handleSync(repo)}
              disabled={!!syncingId}
            >
              <RefreshCw
                className={`h-4 w-4 ${isSyncing ? "animate-spin" : ""}`}
              />
              {isSyncing ? "Syncing" : "Sync"}
            </Button>
          );
        },
      },
    ],
    [handleSync, syncingId],
  );

  const table = useReactTable({
    data: repositories,
    columns,
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <DashboardPageLayout
      signedOut={{
        message: "Sign in to view Git Projects.",
        forceRedirectUrl: "/git-projects",
        signUpForceRedirectUrl: "/git-projects",
      }}
      title="Git Projects"
      description={`${repositories.length} repositor${repositories.length === 1 ? "y" : "ies"} tracked.`}
      stickyHeader
    >
      {syncResult && (
        <div
          className={`mb-4 flex items-start gap-3 rounded-xl border p-3 text-sm ${
            syncResult.error
              ? "border-[color:rgba(248,113,113,0.35)] bg-[color:rgba(248,113,113,0.08)] text-[color:var(--danger)]"
              : "border-[color:rgba(52,211,153,0.35)] bg-[color:rgba(52,211,153,0.08)] text-[color:var(--success)]"
          }`}
        >
          {syncResult.error ? (
            <AlertCircle className="mt-0.5 h-4 w-4 shrink-0" />
          ) : (
            <CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0" />
          )}
          <div className="min-w-0">
            <strong className="break-words">{syncResult.repoName}</strong>{" "}
            {syncResult.error ? (
              <span>{syncResult.error}</span>
            ) : (
              <span>
                synced: {syncResult.created} created, {syncResult.updated}{" "}
                updated, {syncResult.open} open, {syncResult.closed} closed
              </span>
            )}
          </div>
        </div>
      )}

      <div className="mb-4 flex flex-wrap gap-3">
        <Link href="/git-projects/connections">
          <Button variant="outline" size="sm">
            Connections
          </Button>
        </Link>
        <Link href="/git-projects/repositories">
          <Button variant="outline" size="sm">
            Manage Repos
          </Button>
        </Link>
      </div>

      {error ? (
        <div className="surface-muted mb-4 rounded-xl p-4 text-sm text-[color:var(--danger)]">
          {error}
        </div>
      ) : null}

      <div className="overflow-hidden rounded-xl border border-[color:var(--border)] bg-[color:var(--surface)] shadow-lush">
        <DataTable
          table={table}
          isLoading={loading}
          emptyState={{
            icon: <GitBranch className="h-12 w-12" />,
            title: "No repositories tracked yet",
            description:
              "Connect a Git provider and add repositories so Pipeline can track issues for Git Projects.",
            actionHref: "/git-projects/connections",
            actionLabel: "Set up connection",
          }}
        />
      </div>
    </DashboardPageLayout>
  );
}
