"use client";

// /listem'deki "tercihlerin değişmiş" modalı: kayıtlı liste hangi tercihlerle
// kurulduysa (rapor params) kullanıcının güncel profili ondan ayrıldığında
// liste başlığındaki buton belirir; bu modal o butonun içeriğidir — hangi
// alanların değiştiğini gösterir ve listeyi yeni tercihlere göre yeniden
// kurmayı önerir.
//
// Yeniden kurulum normal üretimle AYNI kapıdan geçer (listeOlustur): 3 kredi,
// aynı requestId idempotency'si, aynı kredi-yetersiz/iade davranışı. Ayrı bir
// "güncelleme" ürünü ya da indirimli yol yok — kullanıcı yeni bir liste alıyor,
// bedeli de yeni liste bedeli.
//
// Renk: modalın kabuğu marka primary'si (bg-primary/10 ikon hücresi), ana
// aksiyon ise ürünün CTA turuncusu — kilidi açan, kredi harcayan, ödemeye
// götüren butonlar site genelinde bu tonda. Amber bilerek kullanılmıyor:
// sarı bu üründe risk dilinin "az riskli" tonu (bkz. rapor-listesi
// RISK_STIL).
//
// Fark tablosunun içi ayrı bir dil: kırmızı/yeşil burada risk değil diff
// anlamında (eski değer / yeni değer). Karışmasın diye tablo kendi kutusuna
// kapalı duruyor ve her hücrede −/+ işareti var — risk noktalarında olduğu
// gibi renk tek başına anlam taşımıyor.

import { useMemo, useRef, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { ArrowRight, Check, RefreshCcw, SlidersHorizontal } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogTitle,
} from "@/components/ui/dialog";
import { olay, siraKovasi } from "@/lib/analitik";
import { useTercihProfili } from "@/features/liste/hooks/use-tercih-profili";
import { listeOlustur } from "@/features/rapor/rapor-actions";
import type { RaporParams } from "@/features/rapor/types/rapor";
import { farkSatirlari, tercihFarki } from "@/features/rapor/tercih-farki";
import { useUretimMesaji } from "./uretim-mesaji";

type Durum =
  | { ad: "bekliyor" }
  | { ad: "uretiliyor" }
  | { ad: "tamamlandi" }
  | { ad: "kredi-yetersiz" }
  | { ad: "hata"; mesaj: string };

export function TercihDegistiModali({
  open,
  onOpenChange,
  params,
  kredi,
  raporKredi,
  hasPaket,
}: {
  open: boolean;
  onOpenChange: (acik: boolean) => void;
  /** Kayıtlı listenin üretildiği tercihler */
  params: RaporParams;
  kredi: number;
  raporKredi: number;
  hasPaket: boolean;
}) {
  const router = useRouter();
  const profil = useTercihProfili();
  const [durum, setDurum] = useState<Durum>({ ad: "bekliyor" });
  // Aynı deneme için sabit requestId: cevabı kaybolan istekte retry çifte
  // harcamaz (bkz. liste-uretici.tsx ve spendCredits idempotency'si).
  const requestIdRef = useRef<string | null>(null);

  const farklar = useMemo(
    () => (profil ? tercihFarki(params, profil) : []),
    [params, profil],
  );
  const satirlar = useMemo(
    () => (profil ? farkSatirlari(params, profil, farklar) : []),
    [params, profil, farklar],
  );

  // Üretim sırasında modal kapanmaz: istek 30 sn kadar sürüyor ve kredi çoktan
  // harcanmış oluyor — kullanıcı yanlışlıkla ESC'leyip sonucu kaçırmasın.
  const kilitli = durum.ad === "uretiliyor";

  async function guncelle() {
    if (!profil) return;
    if (!requestIdRef.current) requestIdRef.current = crypto.randomUUID();
    setDurum({ ad: "uretiliyor" });

    try {
      const sonuc = await listeOlustur({
        sira: profil.sira,
        tur: profil.tur,
        secimler: profil.secimler,
        requestId: requestIdRef.current,
      });
      requestIdRef.current = null;
      if (sonuc.ok) {
        olay("liste_guncellendi", {
          tur: profil.tur,
          sira_kovasi: siraKovasi(profil.sira),
          degisen_alan: farklar.length,
        });
        toast.success("Listen yeni tercihlerine göre yeniden kuruldu.");
        // Sunucu params'ı tazelenince fark kalmaz ve başlıktaki buton
        // kendiliğinden "Tercihlerimi düzenle"ye döner.
        setDurum({ ad: "tamamlandi" });
        router.refresh();
        return;
      }
      if (sonuc.code === "KREDI" || sonuc.code === "PAKET") {
        olay("kredi_bitti");
        setDurum({ ad: "kredi-yetersiz" });
      } else if (sonuc.code === "AUTH") {
        router.push(`/giris?callback=${encodeURIComponent("/listem")}`);
      } else {
        setDurum({ ad: "hata", mesaj: sonuc.error });
      }
    } catch {
      setDurum({
        ad: "hata",
        mesaj: "Beklenmeyen bir hata oluştu, tekrar dener misin?",
      });
    }
  }

  const krediYeter = kredi >= raporKredi;

  return (
    <Dialog
      open={open}
      onOpenChange={(v) => {
        if (kilitli) return;
        onOpenChange(v);
      }}
    >
      <DialogContent
        showCloseButton={!kilitli}
        onEscapeKeyDown={(e) => {
          if (kilitli) e.preventDefault();
        }}
        onPointerDownOutside={(e) => {
          if (kilitli) e.preventDefault();
        }}
        onInteractOutside={(e) => {
          if (kilitli) e.preventDefault();
        }}
        className="max-h-[92dvh] overflow-y-auto p-6 sm:max-w-md"
      >
        {durum.ad === "tamamlandi" ? (
          <div className="flex flex-col gap-4">
            <span className="flex size-10 items-center justify-center rounded-full bg-emerald-100 text-emerald-700">
              <Check className="size-5" aria-hidden />
            </span>
            <div className="flex flex-col gap-1.5">
              <DialogTitle className="text-lg">Listen güncellendi</DialogTitle>
              <DialogDescription>
                Yeni tercihlerine göre yeniden kuruldu — arkadaki liste birkaç
                saniye içinde tazelenir.
              </DialogDescription>
            </div>
            <Button
              type="button"
              onClick={() => onOpenChange(false)}
              className="cursor-pointer self-start transition-[background-color,transform] duration-200 active:scale-[0.97]"
            >
              Listeme dön
              <ArrowRight className="size-4" aria-hidden />
            </Button>
          </div>
        ) : (
          <div className="flex flex-col gap-4">
            <div className="flex items-start gap-3 pr-9">
              <span className="flex size-10 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary">
                <SlidersHorizontal className="size-5" aria-hidden />
              </span>
              <div className="flex min-w-0 flex-col gap-1.5">
                <DialogTitle className="text-lg">
                  Tercihlerin değişmiş
                </DialogTitle>
                {/* Hangi alanların değiştiği hemen altındaki diff
                    tablosunda zaten duruyor; açıklama yalnızca sonucu ve
                    bedeli söylüyor. */}
                <DialogDescription>
                  Listen eski tercihlerinle kuruldu. Yeni liste bunun yerine
                  geçer ve {raporKredi} kredi düşer.
                </DialogDescription>
              </div>
            </div>

            {/* Diff yerleşimi: alan adı üstte, eski ve yeni değer yan yana
                iki hücrede — klasik diff dili (eski kırmızı, yeni yeşil
                zemin). −/+ işaretleri ve sr-only "Eski:/Yeni:" etiketleri
                sayesinde renk tek başına anlam taşımaz. */}
            <dl className="overflow-hidden rounded-xl border border-slate-200 text-sm">
              {satirlar.map((satir, i) => (
                <div
                  key={satir.alan}
                  className={i > 0 ? "border-t border-slate-200" : undefined}
                >
                  <dt className="bg-slate-50 px-3 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-slate-500">
                    {satir.etiket}
                  </dt>
                  <dd className="grid grid-cols-2 divide-x divide-slate-200">
                    <span className="flex min-w-0 gap-1.5 bg-red-50 px-3 py-2">
                      <span
                        aria-hidden
                        className="select-none font-mono text-red-400"
                      >
                        −
                      </span>
                      <span className="sr-only">Eski:</span>
                      <span className="min-w-0 break-words text-red-900/80">
                        {satir.eski}
                      </span>
                    </span>
                    <span className="flex min-w-0 gap-1.5 bg-emerald-50 px-3 py-2">
                      <span
                        aria-hidden
                        className="select-none font-mono text-emerald-600"
                      >
                        +
                      </span>
                      <span className="sr-only">Yeni:</span>
                      <span className="min-w-0 break-words font-semibold text-emerald-900">
                        {satir.yeni}
                      </span>
                    </span>
                  </dd>
                </div>
              ))}
            </dl>

            {durum.ad === "uretiliyor" ? (
              <UretimSatiri />
            ) : durum.ad === "kredi-yetersiz" ? (
              <KrediYetersiz hasPaket={hasPaket} raporKredi={raporKredi} />
            ) : (
              // Aksiyon satırı: solda ikincil çıkış (outline), sağda ana
              // aksiyon (turuncu). Turuncu ürünün kendi CTA rengi — kilidi
              // açan, kredi harcayan, ödeme yaptıran yollar hep bu tonda.
              <div className="flex flex-col gap-3">
                {durum.ad === "hata" ? (
                  <p className="text-sm text-red-700">{durum.mesaj}</p>
                ) : null}
                {!krediYeter && durum.ad !== "hata" ? (
                  <p className="text-xs text-slate-500">
                    Güncelleme {raporKredi} kredi; bakiyen {kredi} kredi.
                  </p>
                ) : null}
                <div className="flex flex-wrap items-center justify-end gap-2">
                  <Button
                    type="button"
                    variant="outline"
                    onClick={() => onOpenChange(false)}
                    className="cursor-pointer transition-[background-color,transform] duration-200 active:scale-[0.97]"
                  >
                    Şimdilik kalsın
                  </Button>
                  {durum.ad === "hata" ? (
                    <Button
                      onClick={() => void guncelle()}
                      className="cursor-pointer bg-orange-500 text-white transition-[background-color,transform] duration-200 active:scale-[0.97] hover:bg-orange-600"
                    >
                      <RefreshCcw className="size-4" aria-hidden />
                      Tekrar dene
                    </Button>
                  ) : krediYeter ? (
                    <Button
                      onClick={() => void guncelle()}
                      className="cursor-pointer bg-orange-500 text-white transition-[background-color,transform] duration-200 active:scale-[0.97] hover:bg-orange-600"
                    >
                      Listemi güncelle — {raporKredi} kredi
                      <ArrowRight className="size-4" aria-hidden />
                    </Button>
                  ) : (
                    <Button
                      asChild
                      className="cursor-pointer bg-orange-500 text-white transition-[background-color,transform] duration-200 active:scale-[0.97] hover:bg-orange-600"
                    >
                      <Link href="/paket">
                        {hasPaket
                          ? "Kredi yükle ve güncelle"
                          : "Paketi aktive et"}
                        <ArrowRight className="size-4" aria-hidden />
                      </Link>
                    </Button>
                  )}
                </div>
              </div>
            )}
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}

function UretimSatiri() {
  const mesaj = useUretimMesaji();
  return (
    <div className="flex flex-col gap-1">
      <p className="flex items-center gap-2 text-sm font-medium text-slate-900">
        <RefreshCcw className="size-4 animate-spin text-primary" aria-hidden />
        Listen yeni tercihlerine göre kuruluyor…
      </p>
      <p className="text-sm text-slate-600">{mesaj}</p>
      <p className="text-xs text-slate-500">
        Bu işlem yarım dakika kadar sürebilir, sayfayı kapatma.
      </p>
    </div>
  );
}

function KrediYetersiz({
  hasPaket,
  raporKredi,
}: {
  hasPaket: boolean;
  raporKredi: number;
}) {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <p className="w-full text-sm text-slate-600">
        {hasPaket
          ? `Güncelleme ${raporKredi} kredi ve bakiyen yetmedi. Kredi yüklediğinde listen ve sohbet geçmişin duruyor, kaldığın yerden devam edersin.`
          : `Güncelleme ${raporKredi} kredi ve bakiyen yetmedi. Tercih Dönemi Paketi'yle kredilerin, tam liste, PDF ve revizyon hakları birlikte gelir.`}
      </p>
      <Button
        asChild
        className="cursor-pointer bg-orange-500 text-white transition-[background-color,transform] duration-200 active:scale-[0.97] hover:bg-orange-600"
      >
        <Link href="/paket">
          {hasPaket ? "Kredi yükle" : "Paketi aktive et"}
          <ArrowRight className="size-4" aria-hidden />
        </Link>
      </Button>
    </div>
  );
}
