"use client";

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

import {
  type ColumnDef,
  getCoreRowModel,
  useReactTable,
} from "@tanstack/react-table";
import { CircleDot, ExternalLink, XCircle } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { DataTable } from "@/components/tables/DataTable";
import { CloseForgejoIssueDialog } from "@/components/git/CloseForgejoIssueDialog";
import type { ForgejoIssue, ForgejoIssueLabel } from "@/lib/api-forgejo";

/** Normalize a Forgejo label color to a valid 6-char hex string or null. */
function normalizeLabelColor(raw: string | null | undefined): string | null {
  if (!raw) return null;
  const hex = raw.replace(/^#+/, "");
  return /^[0-9a-fA-F]{3,6}$/.test(hex) ? `#${hex.padEnd(6, "0")}` : null;
}

/** Return white or dark text based on WCAG relative luminance of a hex background. */
function labelTextColor(hex: string): string {
  const h = hex.replace("#", "");
  const r = parseInt(h.slice(0, 2), 16) / 255;
  const g = parseInt(h.slice(2, 4), 16) / 255;
  const b = parseInt(h.slice(4, 6), 16) / 255;
  const lin = (c: number) =>
    c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
  const L = 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
  return L > 0.179 ? "#1a1a1a" : "#ffffff";
}

function LabelChip({ label }: { label: ForgejoIssueLabel }) {
  const bg = normalizeLabelColor(label.color);
  return (
    <Badge
      variant="outline"
      className="shrink-0 text-xs"
      style={
        bg
          ? { backgroundColor: bg, color: labelTextColor(bg), borderColor: bg }
          : undefined
      }
      title={label.description ?? label.name}
    >
      {label.name}
    </Badge>
  );
}

export type ForgejoIssuesTableProps = {
  issues: ForgejoIssue[];
  isLoading?: boolean;
  onRefresh: () => void;
};

export function ForgejoIssuesTable({
  issues,
  isLoading = false,
  onRefresh,
}: ForgejoIssuesTableProps) {
  const [closeIssueDialogOpen, setCloseIssueDialogOpen] = useState(false);
  const [issueToClose, setIssueToClose] = useState<ForgejoIssue | null>(null);

  const handleCloseClick = useCallback((issue: ForgejoIssue) => {
    setIssueToClose(issue);
    setCloseIssueDialogOpen(true);
  }, []);

  const handleCloseSuccess = () => {
    onRefresh();
  };

  const columns: ColumnDef<ForgejoIssue>[] = useMemo(
    () => [
      {
        accessorKey: "forgejo_issue_number",
        header: "#",
        cell: ({ row }) => (
          <a
            href={row.original.html_url}
            target="_blank"
            rel="noopener noreferrer"
            className="inline-flex items-center gap-1 font-mono text-sm text-[color:var(--accent)] hover:underline"
          >
            #{row.original.forgejo_issue_number}
            <ExternalLink className="h-3 w-3" />
          </a>
        ),
      },
      {
        accessorKey: "title",
        header: "Title",
        cell: ({ row }) => (
          <div
            className="max-w-[28rem] truncate font-medium text-strong"
            title={row.original.title}
          >
            {row.original.title}
          </div>
        ),
      },
      {
        accessorKey: "body_preview",
        header: "Description",
        cell: ({ row }) => {
          const body = row.original.body_preview;
          if (!body) return null;
          const truncated = body.length > 120 ? body.slice(0, 120) + "…" : body;
          return (
            <div className="max-w-xs truncate text-sm text-muted" title={body}>
              {truncated}
            </div>
          );
        },
      },
      {
        accessorKey: "state",
        header: "State",
        cell: ({ row }) => {
          const state = row.original.state;
          return (
            <Badge variant={state === "open" ? "success" : "default"}>
              {state}
            </Badge>
          );
        },
      },
      {
        accessorKey: "labels",
        header: "Labels",
        cell: ({ row }) => {
          const labels = row.original.labels;
          if (!labels || labels.length === 0) return null;
          const visible = labels.slice(0, 3);
          const overflow = labels.length - visible.length;
          return (
            <div className="flex max-w-[240px] flex-wrap gap-1">
              {visible.map((label, i) => (
                <LabelChip key={i} label={label} />
              ))}
              {overflow > 0 && (
                <span className="self-center text-xs text-muted">
                  +{overflow}
                </span>
              )}
            </div>
          );
        },
      },
      {
        accessorKey: "author",
        header: "Author",
        cell: ({ row }) => (
          <span className="block max-w-[160px] truncate text-muted">
            {row.original.author || "Unknown"}
          </span>
        ),
      },
      {
        accessorKey: "forgejo_updated_at",
        header: "Updated",
        cell: ({ row }) => {
          try {
            return (
              <span className="whitespace-nowrap text-muted">
                {new Date(row.original.forgejo_updated_at).toLocaleDateString()}
              </span>
            );
          } catch {
            return (
              <span className="text-muted">
                {row.original.forgejo_updated_at}
              </span>
            );
          }
        },
      },
      {
        id: "actions",
        header: "Actions",
        cell: ({ row }) => {
          const issue = row.original;
          if (issue.state !== "open" || issue.is_pull_request) return null;
          return (
            <Button
              variant="ghost"
              size="sm"
              className="h-8 w-8 p-0 text-[color:var(--danger)] hover:bg-[color:rgba(248,113,113,0.08)]"
              onClick={() => handleCloseClick(issue)}
              title="Close issue"
            >
              <XCircle className="h-4 w-4" />
            </Button>
          );
        },
      },
    ],
    [handleCloseClick],
  );
  const table = useReactTable({
    data: issues,
    columns,
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <>
      <div className="overflow-hidden rounded-xl border border-[color:var(--border)] bg-[color:var(--surface)] shadow-lush">
        <DataTable
          table={table}
          isLoading={isLoading}
          loadingLabel="Loading Git Project issues…"
          tableClassName="min-w-[960px] w-full text-left text-sm"
          emptyState={{
            icon: <CircleDot className="h-12 w-12" />,
            title: "No Git Project issues found",
            description:
              "Sync a repository to pull issues into Pipeline, or adjust your filters.",
          }}
        />
      </div>
      <CloseForgejoIssueDialog
        issue={issueToClose}
        open={closeIssueDialogOpen}
        onOpenChange={setCloseIssueDialogOpen}
        onCloseSuccess={handleCloseSuccess}
      />
    </>
  );
}
