"use client";

import { FormEvent, useEffect, useMemo, useState } from "react";

import { useLocale } from "@/components/providers/locale-provider";
import { useCurrentUser } from "@/hooks/use-current-user";
import type { ApiErrorResponse, DetailResponse } from "@/types/api";
import type { GradePriceStandardRecord, GradeRecord, MasterStatus } from "@/types/master-data";

type PriceStandardForm = {
  start_date: string;
  end_date: string;
  min_price: string;
  max_price: string;
  notes: string;
};

type FormValues = {
  code: string;
  is_mangkok: boolean;
  name: string;
  description: string;
  status: MasterStatus;
  buy_price_standards: PriceStandardForm[];
  sell_price_standards: PriceStandardForm[];
};

const emptyPriceStandard = (): PriceStandardForm => ({
  start_date: "",
  end_date: "",
  min_price: "",
  max_price: "",
  notes: ""
});

const emptyForm: FormValues = {
  code: "",
  is_mangkok: false,
  name: "",
  description: "",
  status: "ACTIVE",
  buy_price_standards: [],
  sell_price_standards: []
};

const PAGE_SIZE = 20;

export function GradesClient() {
  const { dict } = useLocale();
  const { canEditCode } = useCurrentUser();
  const [items, setItems] = useState<GradeRecord[]>([]);
  const [search, setSearch] = useState("");
  const [page, setPage] = useState(1);
  const [form, setForm] = useState<FormValues>(emptyForm);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function loadItems() {
    setLoading(true);
    setError(null);
    try {
      const response = await fetch("/api/v1/grades", { cache: "no-store" });
      const payload = (await response.json()) as { data: GradeRecord[] };
      if (!response.ok) throw new Error(dict.master.loadError);
      setItems(payload.data);
    } catch (err) {
      setError(err instanceof Error ? err.message : dict.master.loadError);
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    void loadItems();
  }, []);

  const filteredItems = useMemo(() => {
    const keyword = search.trim().toLowerCase();
    if (!keyword) return items;

    return items.filter((item) => {
      const haystacks = [
        item.code,
        item.name,
        item.legacy_code ?? "",
        item.description ?? "",
        item.is_mangkok ? "mangkok" : "non-mangkok"
      ];

      return haystacks.some((value) => value.toLowerCase().includes(keyword));
    });
  }, [items, search]);

  const totalPages = Math.max(1, Math.ceil(filteredItems.length / PAGE_SIZE));
  const safePage = Math.min(page, totalPages);
  const pagedItems = useMemo(() => {
    const startIndex = (safePage - 1) * PAGE_SIZE;
    return filteredItems.slice(startIndex, startIndex + PAGE_SIZE);
  }, [filteredItems, safePage]);

  useEffect(() => {
    setPage(1);
  }, [search]);

  useEffect(() => {
    if (page > totalPages) {
      setPage(totalPages);
    }
  }, [page, totalPages]);

  function resetForm() {
    setEditingId(null);
    setForm(emptyForm);
    setError(null);
  }

  function mapPriceStandards(items: GradePriceStandardRecord[]): PriceStandardForm[] {
    return items.map((item) => ({
      start_date: item.start_date,
      end_date: item.end_date ?? "",
      min_price: String(item.min_price),
      max_price: String(item.max_price),
      notes: item.notes ?? ""
    }));
  }

  function startEdit(item: GradeRecord) {
    setEditingId(item.id);
    setForm({
      code: item.code,
      is_mangkok: item.is_mangkok,
      name: item.name,
      description: item.description ?? "",
      status: item.status as MasterStatus,
      buy_price_standards: mapPriceStandards(item.buy_price_standards),
      sell_price_standards: mapPriceStandards(item.sell_price_standards)
    });
    setError(null);
  }

  function updatePriceStandard(
    kind: "buy_price_standards" | "sell_price_standards",
    index: number,
    field: keyof PriceStandardForm,
    value: string
  ) {
    setForm((current) => ({
      ...current,
      [kind]: current[kind].map((item, itemIndex) =>
        itemIndex === index ? { ...item, [field]: value } : item
      )
    }));
  }

  function addPriceStandard(kind: "buy_price_standards" | "sell_price_standards") {
    setForm((current) => ({
      ...current,
      [kind]: [...current[kind], emptyPriceStandard()]
    }));
  }

  function removePriceStandard(kind: "buy_price_standards" | "sell_price_standards", index: number) {
    setForm((current) => ({
      ...current,
      [kind]: current[kind].filter((_, itemIndex) => itemIndex !== index)
    }));
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSubmitting(true);
    setError(null);

    try {
      const response = await fetch(editingId ? `/api/v1/grades/${editingId}` : "/api/v1/grades", {
        method: editingId ? "PUT" : "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          ...form,
          buy_price_standards: form.buy_price_standards.map((item) => ({
            ...item,
            min_price: Number(item.min_price || 0),
            max_price: Number(item.max_price || 0)
          })),
          sell_price_standards: form.sell_price_standards.map((item) => ({
            ...item,
            min_price: Number(item.min_price || 0),
            max_price: Number(item.max_price || 0)
          }))
        })
      });

      const payload = (await response.json()) as DetailResponse<GradeRecord> | ApiErrorResponse;
      if (!response.ok) {
        if ("errors" in payload && payload.errors) {
          const firstError = Object.values(payload.errors)[0]?.[0];
          throw new Error(firstError ?? payload.message ?? dict.common.requestFailed);
        }
        throw new Error("message" in payload ? payload.message : dict.common.requestFailed);
      }

      resetForm();
      await loadItems();
    } catch (err) {
      setError(err instanceof Error ? err.message : dict.master.saveError);
    } finally {
      setSubmitting(false);
    }
  }

  async function handleDelete(id: string) {
    if (!window.confirm(`${dict.common.delete} grade ini?`)) return;
    try {
      const response = await fetch(`/api/v1/grades/${id}`, { method: "DELETE" });
      if (!response.ok) {
        const payload = (await response.json()) as ApiErrorResponse;
        throw new Error(payload.message);
      }
      if (editingId === id) resetForm();
      await loadItems();
    } catch (err) {
      setError(err instanceof Error ? err.message : dict.master.deleteError);
    }
  }

  return (
    <section className="grid gap-6 xl:grid-cols-[1.06fr_0.94fr]">
      <div className="ops-card p-6">
        <div className="flex items-start justify-between gap-4">
          <div>
            <p className="ops-overline">{dict.master.overline}</p>
            <h2 className="mt-2 text-[28px] font-semibold tracking-tight text-ink">
              {editingId ? `${dict.common.edit} Grade` : `${dict.master.add} Grade`}
            </h2>
            <p className="mt-3 text-[13px] leading-6 text-slate-500">
              Master grade utama, lengkap dengan standar harga beli dan jual.
            </p>
          </div>
          {editingId ? <button type="button" onClick={resetForm} className="ops-btn-secondary">{dict.common.cancelEdit}</button> : null}
        </div>

        <form className="mt-6 space-y-5" onSubmit={handleSubmit}>
          <div className="grid gap-4 md:grid-cols-2">
            <Field
              label={dict.master.code}
              value={form.code}
              readOnly={!canEditCode}
              placeholder={canEditCode ? (form.is_mangkok ? "MGK00001" : "GRD00001") : "Auto"}
              onChange={(value) => setForm((current) => ({ ...current, code: value }))}
            />
            <Field label={dict.master.name} value={form.name} onChange={(value) => setForm((current) => ({ ...current, name: value }))} />
          </div>

          <label className="flex items-center gap-3 rounded-lg border border-line/70 bg-slate-50/70 px-4 py-3 text-sm text-ink">
            <input
              type="checkbox"
              checked={form.is_mangkok}
              onChange={(event) => setForm((current) => ({ ...current, is_mangkok: event.target.checked }))}
              className="h-4 w-4 rounded border-line text-emerald-600 focus:ring-emerald-500"
            />
            <span>Ini grade mangkok</span>
          </label>

          <label className="block">
            <span className="ops-label">{dict.master.description}</span>
            <textarea value={form.description} onChange={(event) => setForm((current) => ({ ...current, description: event.target.value }))} rows={3} className="ops-textarea" />
          </label>

          <PriceStandardsSection
            title="Standar harga beli"
            items={form.buy_price_standards}
            onAdd={() => addPriceStandard("buy_price_standards")}
            onRemove={(index) => removePriceStandard("buy_price_standards", index)}
            onChange={(index, field, value) => updatePriceStandard("buy_price_standards", index, field, value)}
          />

          <PriceStandardsSection
            title="Standar harga jual"
            items={form.sell_price_standards}
            onAdd={() => addPriceStandard("sell_price_standards")}
            onRemove={(index) => removePriceStandard("sell_price_standards", index)}
            onChange={(index, field, value) => updatePriceStandard("sell_price_standards", index, field, value)}
          />

          <label className="block">
            <span className="ops-label">{dict.master.status}</span>
            <select value={form.status} onChange={(event) => setForm((current) => ({ ...current, status: event.target.value as MasterStatus }))} className="ops-select">
              <option value="ACTIVE">{dict.master.active}</option>
              <option value="INACTIVE">{dict.master.inactive}</option>
            </select>
          </label>

          {error ? <div className="rounded border border-ember/30 bg-ember/10 px-4 py-3 text-sm text-ember">{error}</div> : null}

          <button type="submit" disabled={submitting} className="ops-btn-primary">
            {submitting ? dict.common.processing : editingId ? `${dict.master.update} grade` : `${dict.master.add} grade`}
          </button>
        </form>
      </div>

      <div className="ops-table-shell">
        <div className="ops-section-head">
          <div>
            <p className="ops-title">{dict.master.list} Grades</p>
            <p className="ops-copy">Master baru untuk transisi ke struktur grade tunggal.</p>
          </div>
          <div className="ops-chip-muted">{items.length} {dict.master.dataCount}</div>
        </div>

        {loading ? (
          <div className="px-6 py-8 text-sm text-ink/60">{dict.common.loading}</div>
        ) : items.length === 0 ? (
          <div className="px-6 py-8 text-sm text-ink/60">{dict.master.noData}</div>
        ) : (
          <>
            <div className="border-t border-line/70 px-6 py-4">
              <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
                <div className="w-full max-w-xl">
                  <label className="block">
                    <span className="ops-label">Cari grade</span>
                    <input
                      value={search}
                      onChange={(event) => setSearch(event.target.value)}
                      placeholder="Cari code, nama, legacy code, atau deskripsi..."
                      className="ops-input"
                    />
                  </label>
                </div>
                <div className="text-sm text-slate-500">
                  Menampilkan {pagedItems.length === 0 ? 0 : (safePage - 1) * PAGE_SIZE + 1}-
                  {(safePage - 1) * PAGE_SIZE + pagedItems.length} dari {filteredItems.length} grade
                </div>
              </div>
            </div>

            {filteredItems.length === 0 ? (
              <div className="px-6 py-8 text-sm text-ink/60">
                Tidak ada grade yang cocok dengan pencarian.
              </div>
            ) : (
              <>
          <div className="overflow-x-auto">
            <table className="ops-table">
              <thead>
                <tr>
                  <th>{dict.master.code}</th>
                  <th>{dict.master.name}</th>
                  <th>Tipe</th>
                  <th>Standar Harga</th>
                  <th>{dict.master.status}</th>
                  <th>{dict.common.actions}</th>
                </tr>
              </thead>
              <tbody>
                {pagedItems.map((item) => (
                  <tr key={item.id}>
                    <td className="font-semibold text-ink">
                      <div>{item.code}</div>
                      {item.legacy_code ? <div className="mt-1 text-xs text-slate-500">Legacy: {item.legacy_code}</div> : null}
                    </td>
                    <td>
                      <div className="font-medium text-ink">{item.name}</div>
                      <div className="mt-1 text-xs text-slate-500">{item.description || "-"}</div>
                    </td>
                    <td>{item.is_mangkok ? "Mangkok" : "Non-mangkok"}</td>
                    <td className="text-slate-600">
                      <div>Beli: {item.buy_price_standards.length} row</div>
                      <div className="mt-1 text-xs">Jual: {item.sell_price_standards.length} row</div>
                    </td>
                    <td>
                      <span className={item.status === "INACTIVE" ? "ops-chip-danger" : "ops-chip-active"}>
                        {item.status === "INACTIVE" ? dict.master.inactive : dict.master.active}
                      </span>
                    </td>
                    <td>
                      <div className="flex gap-2">
                        <button type="button" onClick={() => startEdit(item)} className="ops-btn-secondary">{dict.common.edit}</button>
                        <button type="button" onClick={() => void handleDelete(item.id)} className="ops-btn-danger">{dict.common.delete}</button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
                <div className="flex items-center justify-between gap-3 border-t border-line/70 px-6 py-4">
                  <div className="text-sm text-slate-500">
                    Halaman {safePage} dari {totalPages}
                  </div>
                  <div className="flex items-center gap-2">
                    <button
                      type="button"
                      onClick={() => setPage((current) => Math.max(1, current - 1))}
                      disabled={safePage <= 1}
                      className="ops-btn-secondary disabled:cursor-not-allowed disabled:opacity-50"
                    >
                      Sebelumnya
                    </button>
                    <button
                      type="button"
                      onClick={() => setPage((current) => Math.min(totalPages, current + 1))}
                      disabled={safePage >= totalPages}
                      className="ops-btn-secondary disabled:cursor-not-allowed disabled:opacity-50"
                    >
                      Berikutnya
                    </button>
                  </div>
                </div>
              </>
            )}
          </>
        )}
      </div>
    </section>
  );
}

function Field({
  label,
  value,
  onChange,
  readOnly = false,
  placeholder,
  type = "text"
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  readOnly?: boolean;
  placeholder?: string;
  type?: "text" | "date";
}) {
  return (
    <label className="block">
      <span className="ops-label">{label}</span>
      <input
        type={type}
        value={value}
        readOnly={readOnly}
        placeholder={placeholder}
        onChange={(event) => onChange(event.target.value)}
        className="ops-input"
      />
    </label>
  );
}

function PriceStandardsSection({
  title,
  items,
  onAdd,
  onRemove,
  onChange
}: {
  title: string;
  items: PriceStandardForm[];
  onAdd: () => void;
  onRemove: (index: number) => void;
  onChange: (index: number, field: keyof PriceStandardForm, value: string) => void;
}) {
  return (
    <div className="rounded-lg border border-line/70 bg-slate-50/70 p-4">
      <div className="flex items-center justify-between">
        <h3 className="text-lg font-semibold text-ink">{title}</h3>
        <button type="button" onClick={onAdd} className="ops-btn-secondary">Tambah row</button>
      </div>
      {items.length === 0 ? (
        <p className="mt-3 text-sm text-slate-500">Belum ada data. Bisa diisi nanti.</p>
      ) : (
        <div className="mt-4 space-y-4">
          {items.map((item, index) => (
            <div key={`${title}-${index}`} className="rounded border border-line/70 bg-white p-4">
              <div className="grid gap-4 md:grid-cols-2">
                <Field label="Start date" type="date" value={item.start_date} onChange={(value) => onChange(index, "start_date", value)} />
                <Field label="End date" type="date" value={item.end_date} onChange={(value) => onChange(index, "end_date", value)} />
                <Field label="Min price" value={item.min_price} onChange={(value) => onChange(index, "min_price", value)} />
                <Field label="Max price" value={item.max_price} onChange={(value) => onChange(index, "max_price", value)} />
              </div>
              <label className="mt-4 block">
                <span className="ops-label">Notes</span>
                <textarea value={item.notes} onChange={(event) => onChange(index, "notes", event.target.value)} rows={2} className="ops-textarea" />
              </label>
              <div className="mt-4 flex justify-end">
                <button type="button" onClick={() => onRemove(index)} className="ops-btn-danger">Hapus row</button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
