"use client";

import * as React from "react";
import { AlertTriangle, ArrowRight, Sparkles, Users } from "lucide-react";
import { cn } from "@/lib/utils";
import { fmtRange } from "@/lib/dates";
import { fmtMoney } from "@/lib/format";
import { BLOCK_SOURCE_META, type BlockSource } from "@/lib/domain";
import type { Alternative } from "@/lib/inventory";

export interface ConflictDto {
  kind: string;
  label: string;
  start: string;
  end: string;
}

/**
 * Premium conflict surface: explains why the apartment is unavailable and
 * proposes ranked alternatives. Used by the wizard, extend/split dialogs and
 * the calendar move flow.
 */
export function ConflictAlternatives({ apartmentCode, range, conflicts, alternatives, onPick, currency = "MAD", picking }: { apartmentCode: string; range: { checkIn: string; checkOut: string }; conflicts: ConflictDto[]; alternatives: Alternative[]; onPick?: (alt: Alternative) => void; currency?: string; picking?: string | null }) {
  return (
    <div className="space-y-3 animate-slide-up">
      <div className="rounded-lg border border-negative-500/25 bg-negative-50/70 p-3 dark:bg-negative-500/10">
        <p className="flex items-center gap-2 text-sm font-semibold text-negative-700 dark:text-negative-500">
          <AlertTriangle className="size-4" /> {apartmentCode} is unavailable {fmtRange(range.checkIn, range.checkOut)}
        </p>
        <ul className="mt-1.5 space-y-1 text-xs text-negative-700/90 dark:text-negative-500/90">
          {conflicts.map((c, i) => (
            <li key={i} className="flex items-center gap-2">
              <span className="size-1.5 rounded-full bg-current" />
              <span className="font-medium capitalize">{c.kind === "external" ? "External channel" : c.kind}</span>
              <span>· {c.label}</span>
              <span className="text-negative-700/60">· {fmtRange(c.start, c.end)}</span>
            </li>
          ))}
        </ul>
      </div>
      {alternatives.length ? (
        <div>
          <p className="mb-2 flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider text-fg-muted">
            <Sparkles className="size-3.5 text-gold-500" /> Recommended alternatives
          </p>
          <ul className="space-y-1.5">
            {alternatives.map((a) => (
              <li key={a.id}>
                <button type="button" disabled={!onPick} onClick={() => onPick?.(a)} className={cn("group flex w-full items-center gap-3 rounded-lg border border-border bg-surface p-3 text-left transition", onPick && "hover:border-primary hover:shadow-md")}>
                  <span className="flex size-10 shrink-0 items-center justify-center rounded-md bg-surface-2 font-mono text-sm font-bold group-hover:bg-primary/10 group-hover:text-primary">{a.code}</span>
                  <span className="min-w-0 flex-1">
                    <span className="flex items-center gap-2 text-sm font-medium">
                      {a.name}
                      <span className="text-xs font-normal text-fg-muted">
                        · <Users className="inline size-3" /> {a.maxGuests} · {fmtMoney(a.basePrice, currency)}/n
                      </span>
                    </span>
                    <span className="block truncate text-2xs text-fg-subtle">{a.reasons.join(" · ")}</span>
                  </span>
                  <span className="flex flex-col items-end">
                    <span className={cn("text-sm font-semibold tabular", a.score >= 90 ? "text-positive-600" : a.score >= 80 ? "text-brand-700" : "text-fg")}>{a.score}%</span>
                    <span className="text-2xs text-fg-subtle">match</span>
                  </span>
                  {onPick ? <ArrowRight className={cn("size-4 text-fg-subtle transition group-hover:translate-x-0.5 group-hover:text-primary", picking === a.id && "animate-pulse")} /> : null}
                </button>
              </li>
            ))}
          </ul>
        </div>
      ) : (
        <p className="text-xs text-fg-muted">No other apartment fits these dates and guest count. Try different dates or a split stay.</p>
      )}
    </div>
  );
}

export function SourceChip({ source, className, size = "sm" }: { source: string; className?: string; size?: "sm" | "md" }) {
  const meta = BLOCK_SOURCE_META[source as BlockSource] ?? BLOCK_SOURCE_META.OTHER;
  return (
    <span className={cn("inline-flex items-center gap-1.5 rounded-full border border-border bg-surface font-medium text-fg", size === "sm" ? "px-1.5 py-0.5 text-2xs" : "px-2 py-1 text-xs", className)}>
      <span className="size-1.5 rounded-full" style={{ background: meta.color }} />
      {meta.short}
    </span>
  );
}

export function useAvailabilityCheck() {
  const [state, setState] = React.useState<{ loading: boolean; available: boolean | null; conflicts: ConflictDto[]; alternatives: Alternative[] }>({ loading: false, available: null, conflicts: [], alternatives: [] });
  const check = React.useCallback(async (input: { apartmentId: string; checkIn: string; checkOut: string; guests: number; excludeReservationId?: string }) => {
    setState((s) => ({ ...s, loading: true }));
    const { checkAvailabilityWithAlternatives } = await import("@/lib/actions/inventory");
    const res = await checkAvailabilityWithAlternatives(input);
    if (res.ok) setState({ loading: false, available: res.data.available, conflicts: res.data.conflicts, alternatives: res.data.alternatives });
    else setState({ loading: false, available: null, conflicts: [], alternatives: [] });
    return res;
  }, []);
  return { ...state, check, reset: () => setState({ loading: false, available: null, conflicts: [], alternatives: [] }) };
}
