"use client";

import { useState } from "react";
import { Plus, Trash2 } from "lucide-react";
import { useRepositories } from "@/di/repository-provider";
import { useApiQuery } from "@/presentation/hooks/use-api-query";
import { useApiMutation } from "@/presentation/hooks/use-api-mutation";
import { useT } from "@/shared/i18n/client";
import { Button } from "@/presentation/components/ui/button";
import { Input } from "@/presentation/components/ui/input";
import { Switch } from "@/presentation/components/ui/switch";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/presentation/components/ui/dialog";
import type { DonnaSettings } from "@/domain/entities/donna";

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSaved: () => void;
}

type ModelRow = { model: string; input: string; output: string; cache_read: string; cache_write: string };

type Form = {
  markup: string;
  giftRate: string;
  giftEnabled: boolean;
  usdToEur: string;
  ocrPage: string;
  defaultInput: string;
  defaultOutput: string;
  models: ModelRow[];
};

const text = (value: number | null) => (value === null ? "" : String(value));

const toForm = (s: DonnaSettings): Form => ({
  markup: String(s.markup),
  giftRate: String(Math.round(s.gift_rate * 10000) / 100),
  giftEnabled: s.gift_enabled,
  usdToEur: String(s.usd_to_eur),
  ocrPage: String(s.ocr_page_usd),
  defaultInput: String(s.default_price.input),
  defaultOutput: String(s.default_price.output),
  models: s.models.map((m) => ({
    model: m.model, input: String(m.input), output: String(m.output), cache_read: text(m.cache_read), cache_write: text(m.cache_write),
  })),
});

export function DonnaSettingsDialog({ open, onOpenChange, onSaved }: Props) {
  const t = useT();
  const repo = useRepositories().donnaRepository;
  const [form, setForm] = useState<Form | null>(null);

  const { data } = useApiQuery(() => repo.getSettings(), { enabled: open, deps: [open] });

  const [loaded, setLoaded] = useState(data);
  if (data !== loaded) {
    setLoaded(data);
    setForm(data ? toForm(data) : null);
  }

  const save = useApiMutation(
    (f: Form) =>
      repo.updateSettings({
        markup: Number(f.markup),
        gift_rate: Number(f.giftRate) / 100,
        gift_enabled: f.giftEnabled,
        usd_to_eur: Number(f.usdToEur),
        ocr_page_usd: Number(f.ocrPage),
        default_price: { input: Number(f.defaultInput), output: Number(f.defaultOutput) },
        models: f.models
          .filter((m) => m.model.trim() !== "")
          .map((m) => ({
            model: m.model.trim(),
            input: Number(m.input),
            output: Number(m.output),
            cache_read: m.cache_read === "" ? null : Number(m.cache_read),
            cache_write: m.cache_write === "" ? null : Number(m.cache_write),
          })),
      }),
    {
      successMessage: t.donna.settings.saved,
      onSuccess: () => {
        onSaved();
        onOpenChange(false);
      },
    }
  );

  const set = (patch: Partial<Form>) => setForm((f) => (f ? { ...f, ...patch } : f));
  const setModel = (index: number, patch: Partial<ModelRow>) =>
    setForm((f) => (f ? { ...f, models: f.models.map((m, i) => (i === index ? { ...m, ...patch } : m)) } : f));

  const number = (value: string, onChange: (v: string) => void, step = "0.01", className = "w-28") => (
    <Input type="number" min={0} step={step} value={value} onChange={(e) => onChange(e.target.value)} className={className} />
  );

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-3xl">
        <DialogHeader>
          <DialogTitle>{t.donna.settings.title}</DialogTitle>
        </DialogHeader>

        {form && (
          <div className="space-y-6">
            <p className="text-sm text-muted-foreground">{t.donna.settings.intro}</p>

            <section className="grid gap-4 sm:grid-cols-2">
              <Field label={t.donna.settings.markup} hint={t.donna.settings.markupHint}>
                {number(form.markup, (v) => set({ markup: v }))}
              </Field>
              <Field label={t.donna.settings.usdToEur} hint={t.donna.settings.usdToEurHint}>
                {number(form.usdToEur, (v) => set({ usdToEur: v }), "0.0001")}
              </Field>
              <Field label={t.donna.settings.giftRate} hint={t.donna.settings.giftRateHint}>
                {number(form.giftRate, (v) => set({ giftRate: v }), "0.5")}
              </Field>
              <label className="flex items-center gap-3 text-sm sm:col-span-2">
                <Switch checked={form.giftEnabled} onCheckedChange={(checked) => set({ giftEnabled: checked })} />
                <span>
                  <span className="font-medium">{t.donna.settings.giftEnabled}</span>
                  <span className="block text-xs text-muted-foreground">{t.donna.settings.giftEnabledHint}</span>
                </span>
              </label>
            </section>

            <section className="space-y-2">
              <h4 className="text-sm font-semibold">{t.donna.settings.prices}</h4>
              <p className="text-xs text-muted-foreground">{t.donna.settings.pricesHint}</p>
              <div className="grid grid-cols-[minmax(0,1fr)_repeat(4,5.5rem)_2rem] items-center gap-2 text-xs text-muted-foreground">
                <span>{t.donna.settings.model}</span>
                <span>{t.donna.settings.input}</span>
                <span>{t.donna.settings.output}</span>
                <span>{t.donna.settings.cacheRead}</span>
                <span>{t.donna.settings.cacheWrite}</span>
                <span />
              </div>
              {form.models.map((m, i) => (
                <div key={i} className="grid grid-cols-[minmax(0,1fr)_repeat(4,5.5rem)_2rem] items-center gap-2">
                  <Input value={m.model} placeholder="gpt-5.4" onChange={(e) => setModel(i, { model: e.target.value })} />
                  {number(m.input, (v) => setModel(i, { input: v }), "0.01", "w-full")}
                  {number(m.output, (v) => setModel(i, { output: v }), "0.01", "w-full")}
                  {number(m.cache_read, (v) => setModel(i, { cache_read: v }), "0.01", "w-full")}
                  {number(m.cache_write, (v) => setModel(i, { cache_write: v }), "0.01", "w-full")}
                  <Button size="icon" variant="ghost" onClick={() => set({ models: form.models.filter((_, j) => j !== i) })}>
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </div>
              ))}
              <div className="grid grid-cols-[minmax(0,1fr)_repeat(4,5.5rem)_2rem] items-center gap-2">
                <span className="text-sm">{t.donna.settings.otherModels}</span>
                {number(form.defaultInput, (v) => set({ defaultInput: v }), "0.01", "w-full")}
                {number(form.defaultOutput, (v) => set({ defaultOutput: v }), "0.01", "w-full")}
                <span />
                <span />
                <span />
              </div>
              <Button
                size="sm"
                variant="outline"
                onClick={() => set({ models: [...form.models, { model: "", input: "", output: "", cache_read: "", cache_write: "" }] })}
              >
                <Plus className="mr-1 h-4 w-4" />
                {t.donna.settings.addModel}
              </Button>
              <Field label={t.donna.settings.ocrPage} hint={t.donna.settings.ocrPageHint}>
                {number(form.ocrPage, (v) => set({ ocrPage: v }), "0.0001")}
              </Field>
            </section>

            <div className="flex justify-end gap-2">
              <Button variant="outline" onClick={() => onOpenChange(false)}>
                {t.donna.settings.cancel}
              </Button>
              <Button disabled={save.loading} onClick={() => save.mutate(form)}>
                {t.donna.save}
              </Button>
            </div>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}

function Field({ label, hint, children }: { label: string; hint: string; children: React.ReactNode }) {
  return (
    <label className="block space-y-1 text-sm">
      <span className="font-medium">{label}</span>
      {children}
      <span className="block text-xs text-muted-foreground">{hint}</span>
    </label>
  );
}
