"use client";

import { useState, useMemo } from "react";
import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button";
import { CheckCircle2, ChevronDown, ChevronRight } from "lucide-react";
import type {
  RegistryEntry,
  TrackedDeadline,
  DeadlineResolution,
} from "../types";
import {
  aggregateDeadlines,
  groupDeadlinesByEntry,
  type DeadlineEntryGroup,
  type DeadlineDisplayStatus,
} from "../services/deadline-service";
import { getDeadlineType } from "../services/deadline-catalog";
import { DeadlineResolveDialog } from "./deadline-resolve-dialog";
import { cn } from "@/shared/lib/utils";

interface DeadlineDashboardProps {
  entries: RegistryEntry[];
  onResolveDeadline: (
    entryId: string,
    deadlineId: string,
    resolution: DeadlineResolution,
    note: string,
    chainNext: boolean,
  ) => void;
  onAddChainedDeadline: (
    entryId: string,
    typeId: string,
    startDate: string,
    parentId: string,
  ) => void;
}

function formatFullDate(iso: string): string {
  try {
    return new Date(iso).toLocaleDateString("ro-RO", {
      day: "2-digit",
      month: "long",
      year: "numeric",
    });
  } catch {
    return iso;
  }
}

const VARIANT_DOT: Record<string, string> = {
  green: "bg-green-500",
  yellow: "bg-amber-500",
  red: "bg-red-500",
  blue: "bg-blue-500",
  gray: "bg-muted-foreground",
};

const VARIANT_TEXT: Record<string, string> = {
  green: "text-green-700 dark:text-green-400",
  yellow: "text-amber-700 dark:text-amber-400",
  red: "text-red-700 dark:text-red-400",
  blue: "text-blue-700 dark:text-blue-400",
  gray: "text-muted-foreground",
};

const VARIANT_BG: Record<string, string> = {
  red: "border-red-200 bg-red-50/50 dark:border-red-900 dark:bg-red-950/20",
  yellow:
    "border-amber-200 bg-amber-50/50 dark:border-amber-900 dark:bg-amber-950/20",
};

export function DeadlineDashboard({
  entries,
  onResolveDeadline,
  onAddChainedDeadline,
}: DeadlineDashboardProps) {
  const [urgentOnly, setUrgentOnly] = useState(false);
  const [resolvingEntry, setResolvingEntry] = useState<string | null>(null);
  const [resolvingDeadline, setResolvingDeadline] =
    useState<TrackedDeadline | null>(null);
  const [expandedChains, setExpandedChains] = useState<Set<string>>(new Set());

  const stats = useMemo(() => aggregateDeadlines(entries), [entries]);
  const groups = useMemo(() => groupDeadlinesByEntry(entries), [entries]);

  const filteredGroups = useMemo(() => {
    if (!urgentOnly) return groups;
    return groups
      .map((g) => ({
        ...g,
        mainDeadlines: g.mainDeadlines.filter(
          (m) =>
            m.deadline.resolution === "pending" &&
            (m.status.variant === "yellow" || m.status.variant === "red"),
        ),
      }))
      .filter((g) => g.mainDeadlines.length > 0);
  }, [groups, urgentOnly]);

  const toggleChain = (deadlineId: string) => {
    setExpandedChains((prev) => {
      const next = new Set(prev);
      if (next.has(deadlineId)) next.delete(deadlineId);
      else next.add(deadlineId);
      return next;
    });
  };

  const handleResolveClick = (entryId: string, deadline: TrackedDeadline) => {
    setResolvingEntry(entryId);
    setResolvingDeadline(deadline);
  };

  const handleResolve = (
    resolution: DeadlineResolution,
    note: string,
    chainNext: boolean,
  ) => {
    if (!resolvingEntry || !resolvingDeadline) return;
    onResolveDeadline(
      resolvingEntry,
      resolvingDeadline.id,
      resolution,
      note,
      chainNext,
    );

    if (chainNext) {
      const def = getDeadlineType(resolvingDeadline.typeId);
      if (def?.chainNextTypeId) {
        const resolvedDate = new Date().toISOString().slice(0, 10);
        onAddChainedDeadline(
          resolvingEntry,
          def.chainNextTypeId,
          resolvedDate,
          resolvingDeadline.id,
        );
      }
    }

    setResolvingEntry(null);
    setResolvingDeadline(null);
  };

  return (
    <div className="space-y-4">
      {/* Summary bar */}
      <div className="flex items-center gap-6 rounded-lg border bg-card px-4 py-3">
        <SummaryItem
          count={stats.active}
          label="active"
          variant="green"
          showIfZero
        />
        <SummaryItem count={stats.urgent} label="urgente" variant="yellow" />
        <SummaryItem
          count={stats.overdue}
          label={stats.overdue === 1 ? "depasit" : "depasite"}
          variant="red"
        />

        <div className="ml-auto">
          <Button
            variant={urgentOnly ? "default" : "outline"}
            size="sm"
            onClick={() => setUrgentOnly(!urgentOnly)}
          >
            Doar urgente
          </Button>
        </div>
      </div>

      {/* Grouped deadline list */}
      {filteredGroups.length === 0 ? (
        <p className="py-12 text-center text-sm text-muted-foreground">
          {urgentOnly
            ? "Niciun termen urgent sau depasit."
            : "Niciun termen legal activ."}
        </p>
      ) : (
        <div className="space-y-3">
          {filteredGroups.map((group) => (
            <EntryDeadlineCard
              key={group.entry.id}
              group={group}
              expandedChains={expandedChains}
              onToggleChain={toggleChain}
              onResolve={handleResolveClick}
            />
          ))}
        </div>
      )}

      <DeadlineResolveDialog
        open={resolvingDeadline !== null}
        deadline={resolvingDeadline}
        onOpenChange={(open) => {
          if (!open) {
            setResolvingEntry(null);
            setResolvingDeadline(null);
          }
        }}
        onResolve={handleResolve}
      />
    </div>
  );
}

// ── Summary item ──

function SummaryItem({
  count,
  label,
  variant,
  showIfZero,
}: {
  count: number;
  label: string;
  variant: string;
  showIfZero?: boolean;
}) {
  if (count === 0 && !showIfZero) return null;
  return (
    <div className="flex items-center gap-2">
      <span
        className={cn("h-2.5 w-2.5 rounded-full", VARIANT_DOT[variant])}
      />
      <span className={cn("text-sm font-semibold", VARIANT_TEXT[variant])}>
        {count}
      </span>
      <span className="text-sm text-muted-foreground">{label}</span>
    </div>
  );
}

// ── Entry card with its deadlines ──

function EntryDeadlineCard({
  group,
  expandedChains,
  onToggleChain,
  onResolve,
}: {
  group: DeadlineEntryGroup;
  expandedChains: Set<string>;
  onToggleChain: (id: string) => void;
  onResolve: (entryId: string, deadline: TrackedDeadline) => void;
}) {
  const { entry, mainDeadlines } = group;

  // Worst status for card border color
  const worstVariant = mainDeadlines.reduce<string>((worst, m) => {
    if (m.deadline.resolution !== "pending") return worst;
    const order: Record<string, number> = {
      red: 0,
      yellow: 1,
      blue: 2,
      green: 3,
      gray: 4,
    };
    const cur = order[m.status.variant] ?? 4;
    const w = order[worst] ?? 4;
    return cur < w ? m.status.variant : worst;
  }, "green");

  return (
    <div
      className={cn(
        "rounded-lg border bg-card",
        VARIANT_BG[worstVariant] ?? "",
      )}
    >
      {/* Entry header */}
      <div className="flex items-center gap-3 border-b px-4 py-2.5">
        <span className="font-mono text-xs font-semibold">
          {entry.number}
        </span>
        <span className="text-xs text-muted-foreground">|</span>
        <span className="truncate text-xs">{entry.subject}</span>
        <Badge
          variant="outline"
          className={cn(
            "ml-auto shrink-0 text-[10px]",
            entry.direction === "intrat"
              ? "border-blue-300 text-blue-700 dark:border-blue-800 dark:text-blue-400"
              : "border-orange-300 text-orange-700 dark:border-orange-800 dark:text-orange-400",
          )}
        >
          {entry.direction === "intrat" ? "Intrat" : "Iesit"}
        </Badge>
      </div>

      {/* Deadlines */}
      <div className="divide-y">
        {mainDeadlines.map((item) => {
          const isExpanded = expandedChains.has(item.deadline.id);
          const chainCount = item.chainChildren.length;

          return (
            <div key={item.deadline.id}>
              <DeadlineRow
                deadline={item.deadline}
                status={item.status}
                entryId={entry.id}
                allDeadlines={entry.trackedDeadlines ?? []}
                chainCount={chainCount}
                isExpanded={isExpanded}
                onToggleChain={() => onToggleChain(item.deadline.id)}
                onResolve={onResolve}
              />
              {/* Chain children (expanded) */}
              {isExpanded &&
                chainCount > 0 &&
                item.chainChildren.map((child) => (
                  <DeadlineRow
                    key={child.deadline.id}
                    deadline={child.deadline}
                    status={child.status}
                    entryId={entry.id}
                    isChainChild
                    onResolve={onResolve}
                  />
                ))}
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ── Single deadline row ──

// ── Milestone data for progress bar ──

interface ProgressMilestone {
  position: number; // 0..1 on the progress bar
  label: string;
  isPassed: boolean;
  typeId: string;
  dueDate: string; // ISO date for tooltip
}

function computeMilestones(
  mainDeadline: TrackedDeadline,
  allDeadlines: TrackedDeadline[],
): ProgressMilestone[] {
  const mainStart = new Date(mainDeadline.startDate).getTime();
  const mainDue = new Date(mainDeadline.dueDate).getTime();
  const totalSpan = mainDue - mainStart;
  if (totalSpan <= 0) return [];

  const now = Date.now();
  const milestones: ProgressMilestone[] = [];

  for (const dl of allDeadlines) {
    if (dl.id === mainDeadline.id) continue;
    const def = getDeadlineType(dl.typeId);
    if (!def?.autoTrack) continue;
    if (def.backgroundOnly) continue;

    const dlDue = new Date(dl.dueDate).getTime();
    // Only show milestones that fall within the main deadline's time range
    if (dlDue <= mainStart || dlDue >= mainDue) continue;

    const pos = (dlDue - mainStart) / totalSpan;
    if (pos < 0.03 || pos > 0.97) continue; // too close to edges

    milestones.push({
      position: pos,
      label: getMilestoneLabel(def.id, dlDue < now),
      isPassed: dlDue < now,
      typeId: def.id,
      dueDate: dl.dueDate,
    });
  }

  milestones.sort((a, b) => a.position - b.position);
  return milestones;
}

function getMilestoneLabel(typeId: string, isPassed: boolean): string {
  if (typeId.includes("verificare")) {
    return isPassed
      ? "Verificare expirata — nu se mai pot solicita clarificari"
      : "Termen verificare cerere";
  }
  if (typeId.includes("completari-limit")) {
    return isPassed
      ? "Termen solicitare completari expirat"
      : "Limita solicitare completari";
  }
  if (typeId.includes("comunicare")) {
    return isPassed ? "Termen comunicare expirat" : "Termen comunicare";
  }
  if (typeId.includes("solicitare-aviz")) {
    return isPassed
      ? "Termen solicitare aviz expirat"
      : "Solicitare aviz primar";
  }
  if (typeId.includes("aviz-primar")) {
    return isPassed ? "Aviz primar expirat" : "Aviz primar";
  }
  if (typeId.includes("depunere-comisie")) {
    return isPassed ? "Depunere comisie expirata" : "Depunere la comisie";
  }
  const def = getDeadlineType(typeId);
  return def?.label ?? typeId;
}

// ── Single deadline row ──

function DeadlineRow({
  deadline,
  status,
  entryId,
  allDeadlines,
  chainCount,
  isExpanded,
  isChainChild,
  onToggleChain,
  onResolve,
}: {
  deadline: TrackedDeadline;
  status: DeadlineDisplayStatus;
  entryId: string;
  allDeadlines?: TrackedDeadline[];
  chainCount?: number;
  isExpanded?: boolean;
  isChainChild?: boolean;
  onToggleChain?: () => void;
  onResolve: (entryId: string, deadline: TrackedDeadline) => void;
}) {
  const def = getDeadlineType(deadline.typeId);
  const isPending = deadline.resolution === "pending";

  // Progress calculation
  const totalDays = (() => {
    const start = new Date(deadline.startDate).getTime();
    const due = new Date(deadline.dueDate).getTime();
    return Math.max(1, Math.ceil((due - start) / (1000 * 60 * 60 * 24)));
  })();

  const elapsedDays = (() => {
    const start = new Date(deadline.startDate).getTime();
    const now = Date.now();
    return Math.ceil((now - start) / (1000 * 60 * 60 * 24));
  })();

  const progressPct = isPending
    ? Math.min(100, Math.max(0, (elapsedDays / totalDays) * 100))
    : 100;

  // Milestones on the progress bar (auto-tracked sub-deadlines)
  const milestones = isPending && allDeadlines
    ? computeMilestones(deadline, allDeadlines)
    : [];

  return (
    <div className={cn("px-4 py-2", isChainChild && "bg-muted/30 pl-8")}>
      <div className="flex items-center gap-3">
        {/* Chain expand toggle */}
        {!isChainChild && (chainCount ?? 0) > 0 ? (
          <button
            onClick={onToggleChain}
            className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground"
          >
            {isExpanded ? (
              <ChevronDown className="h-3.5 w-3.5" />
            ) : (
              <ChevronRight className="h-3.5 w-3.5" />
            )}
          </button>
        ) : isChainChild ? (
          <span className="text-muted-foreground/40 text-xs">{"\u2514"}</span>
        ) : (
          <span className="w-3.5" />
        )}

        {/* Type label */}
        <div className="min-w-0 flex-1">
          <span className={cn("text-xs", isChainChild && "text-muted-foreground")}>
            {def?.label ?? deadline.typeId}
          </span>
          {!isChainChild && (chainCount ?? 0) > 0 && (
            <span className="ml-2 text-[10px] text-muted-foreground">
              (+{chainCount} etap{chainCount === 1 ? "a" : "e"})
            </span>
          )}
        </div>

        {/* Progress bar with milestones (only for pending) */}
        {isPending && (
          <div className="hidden w-32 sm:block">
            <div className="relative h-4">
              {/* Track */}
              <div className="absolute top-[7px] left-0 right-0 h-1.5 rounded-full bg-muted">
                <div
                  className={cn(
                    "h-1.5 rounded-full transition-all",
                    status.variant === "red"
                      ? "bg-red-500"
                      : status.variant === "yellow"
                        ? "bg-amber-500"
                        : "bg-green-500",
                  )}
                  style={{ width: `${progressPct}%` }}
                />
              </div>
              {/* Milestone dots */}
              {milestones.map((ms) => (
                <div
                  key={ms.typeId}
                  className="absolute top-[5px] -ml-[5px]"
                  style={{ left: `${ms.position * 100}%` }}
                  title={`${ms.label}\nData maximă: ${formatFullDate(ms.dueDate)}`}
                >
                  <div
                    className={cn(
                      "h-2.5 w-2.5 rounded-full border",
                      ms.isPassed
                        ? "border-muted-foreground/50 bg-muted-foreground/30"
                        : "border-amber-500 bg-amber-400",
                    )}
                  />
                </div>
              ))}
            </div>
          </div>
        )}

        {/* Countdown / status */}
        <div className="shrink-0 text-right">
          {isPending && status.daysRemaining !== null ? (
            <span
              className={cn(
                "text-xs font-medium",
                VARIANT_TEXT[status.variant],
              )}
              title={`Data maximă: ${formatFullDate(deadline.dueDate)}`}
            >
              {status.daysRemaining < 0
                ? `${Math.abs(status.daysRemaining)}z depasit`
                : status.daysRemaining === 0
                  ? "azi"
                  : `${status.daysRemaining}z ramase`}
            </span>
          ) : (
            <span className="text-[10px] text-muted-foreground">
              {status.label}
            </span>
          )}
        </div>

        {/* Resolve button */}
        <div className="w-7 shrink-0">
          {isPending && (
            <Button
              variant="ghost"
              size="icon"
              className="h-7 w-7 text-green-600"
              onClick={() => onResolve(entryId, deadline)}
              title="Rezolva"
            >
              <CheckCircle2 className="h-3.5 w-3.5" />
            </Button>
          )}
        </div>
      </div>

      {/* Milestone legend (below progress bar, only when milestones exist) */}
      {milestones.length > 0 && isPending && (
        <div className="ml-7 mt-1 hidden sm:flex flex-wrap gap-x-3 gap-y-0.5">
          {milestones.map((ms) => (
            <div key={ms.typeId} className="flex items-center gap-1 text-[9px]">
              <span
                className={cn(
                  "h-1.5 w-1.5 rounded-full",
                  ms.isPassed
                    ? "bg-muted-foreground/40"
                    : "bg-amber-400",
                )}
              />
              <span
                className={cn(
                  ms.isPassed
                    ? "text-muted-foreground line-through"
                    : "text-muted-foreground",
                )}
              >
                {ms.isPassed
                  ? getMilestoneLabel(ms.typeId, true)
                  : getMilestoneLabel(ms.typeId, false)}
              </span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
