"use client";

import Link from "next/link";
import { useEffect, useMemo, useState } from "react";

import { useLocale } from "@/components/providers/locale-provider";
import { formatQuantity } from "@/lib/formatters";
import type { ApiErrorResponse, DetailResponse } from "@/types/api";
import type { AdjustmentReasonRecord } from "@/types/master-data";
import type { LotListItem } from "@/types/lot";
import type { StockAdjustmentListItem } from "@/types/stock-adjustment";

type StockAdjustmentForm = {
  lot_id: string;
  adjustment_reason_id: string;
  adjustment_date: string;
  qty_change: string;
  notes: string;
};

const emptyForm = (): StockAdjustmentForm => ({
  lot_id: "",
  adjustment_reason_id: "",
  adjustment_date: new Date().toISOString().slice(0, 10),
  qty_change: "",
  notes: ""
});

const adjustmentReasonCategoryLabels: Record<AdjustmentReasonRecord["category"], string> = {
  ADJUSTMENT: "Penyesuaian / Adjustment",
  SHRINKAGE: "Penyusutan / Shrinkage",
  DAMAGE: "Kerusakan / Damage",
  REGRADE: "Regrade / Regrade"
};

export function StockAdjustmentsClient() {
  const { dict, locale } = useLocale();
  const [items, setItems] = useState<StockAdjustmentListItem[]>([]);
  const [lots, setLots] = useState<LotListItem[]>([]);
  const [reasons, setReasons] = useState<AdjustmentReasonRecord[]>([]);
  const [form, setForm] = useState<StockAdjustmentForm>(emptyForm);
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function loadAll() {
    setLoading(true);
    setError(null);
    try {
      const [itemsRes, lotsRes, reasonsRes] = await Promise.all([
        fetch("/api/v1/stock-adjustments", { cache: "no-store" }),
        fetch("/api/v1/lots", { cache: "no-store" }),
        fetch("/api/v1/adjustment-reasons", { cache: "no-store" })
      ]);

      const itemsPayload = (await itemsRes.json()) as { data: StockAdjustmentListItem[] };
      const lotsPayload = (await lotsRes.json()) as { data: LotListItem[] };
      const reasonsPayload = (await reasonsRes.json()) as { data: AdjustmentReasonRecord[] };

      if (!itemsRes.ok || !lotsRes.ok || !reasonsRes.ok) {
        throw new Error(dict.stockAdjustments.loadingError);
      }

      setItems(itemsPayload.data);
      setLots(lotsPayload.data);
      setReasons(reasonsPayload.data);
    } catch (err) {
      setError(err instanceof Error ? err.message : dict.stockAdjustments.loadingError);
    } finally {
      setLoading(false);
    }
  }

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

  async function createAdjustment() {
    setSubmitting(true);
    setError(null);
    try {
      const response = await fetch("/api/v1/stock-adjustments", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          lot_id: form.lot_id,
          adjustment_reason_id: form.adjustment_reason_id,
          adjustment_date: form.adjustment_date,
          qty_change: Number(form.qty_change),
          notes: form.notes || null
        })
      });

      const payload =
        (await response.json()) as DetailResponse<StockAdjustmentListItem> | 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.stockAdjustments.createError);
      }

      setForm(emptyForm());
      await loadAll();
    } catch (err) {
      setError(err instanceof Error ? err.message : dict.stockAdjustments.createError);
    } finally {
      setSubmitting(false);
    }
  }

  const activeLots = useMemo(
    () => lots.filter((lot) => lot.available_qty > 0),
    [lots]
  );
  const selectedLot = activeLots.find((lot) => lot.id === form.lot_id) ?? null;
  const selectedReason = reasons.find((reason) => reason.id === form.adjustment_reason_id) ?? null;

  return (
    <section className="grid gap-6 xl:grid-cols-[0.92fr_1.08fr]">
      <div className="ops-card p-6">
        <div className="flex items-start justify-between gap-4">
          <div>
            <p className="ops-overline">{dict.stockAdjustments.overline}</p>
            <h2 className="mt-2 text-[28px] font-semibold tracking-tight text-ink">
              {dict.stockAdjustments.createTitle}
            </h2>
            <p className="mt-3 text-[13px] leading-6 text-slate-500">
              {dict.stockAdjustments.helper}
            </p>
          </div>
          <button
            type="button"
            onClick={() => {
              setForm(emptyForm());
              setError(null);
            }}
            className="ops-btn-secondary"
          >
            {dict.common.formReset}
          </button>
        </div>

        <div className="mt-6 space-y-5">
          <SelectField
            label="Lot"
            value={form.lot_id}
            onChange={(value) => setForm((current) => ({ ...current, lot_id: value }))}
            options={activeLots.map((lot) => ({
              value: lot.id,
              label: `${lot.lot_code} · ${lot.grade} · ${lot.available_qty} ${lot.unit_code}`
            }))}
            placeholder={dict.stockAdjustments.chooseActiveLot}
          />

          {selectedLot ? (
            <div className="rounded border border-line/70 bg-slate-50 px-4 py-4 text-sm text-slate-600">
              <div className="font-medium text-ink">{selectedLot.lot_code}</div>
              <div className="mt-1">
                {selectedLot.grade} · {dict.stockAdjustments.available}{" "}
                {selectedLot.available_qty} {selectedLot.unit_code}
              </div>
              <div className="mt-1">{dict.common.warehouse}: {selectedLot.warehouse}</div>
            </div>
          ) : null}

          <SelectField
            label={dict.stockAdjustments.adjustmentReason}
            value={form.adjustment_reason_id}
            onChange={(value) =>
              setForm((current) => ({ ...current, adjustment_reason_id: value }))
            }
            options={reasons.map((reason) => ({
              value: reason.id,
              label: `${reason.code} - ${reason.name} (${adjustmentReasonCategoryLabels[reason.category]})`
            }))}
            placeholder={dict.stockAdjustments.chooseReason}
          />

          {selectedReason ? (
            <div className="rounded border border-line/70 bg-slate-50 px-4 py-4 text-sm text-slate-600">
              <div>
                {dict.stockAdjustments.category}:{" "}
                <span className="font-medium text-ink">
                  {adjustmentReasonCategoryLabels[selectedReason.category]}
                </span>
              </div>
              {selectedReason.description ? (
                <div className="mt-2 text-xs leading-5 text-slate-500">
                  {selectedReason.description}
                </div>
              ) : null}
            </div>
          ) : null}

          <div className="grid gap-4 md:grid-cols-2">
            <Field
              label={dict.stockAdjustments.adjustmentDate}
              type="date"
              value={form.adjustment_date}
              onChange={(value) =>
                setForm((current) => ({ ...current, adjustment_date: value }))
              }
            />
            <Field
              label={dict.stockAdjustments.adjustmentQty}
              value={form.qty_change}
              onChange={(value) => setForm((current) => ({ ...current, qty_change: value }))}
              placeholder={dict.stockAdjustments.adjustmentQtyPlaceholder}
            />
          </div>

          <label className="block">
            <span className="ops-label">{dict.common.notes}</span>
            <textarea
              value={form.notes}
              onChange={(event) =>
                setForm((current) => ({ ...current, notes: event.target.value }))
              }
              rows={4}
              className="ops-textarea"
            />
          </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="button"
            disabled={submitting}
            onClick={() => void createAdjustment()}
            className="ops-btn-primary"
          >
            {submitting ? dict.common.processing : dict.stockAdjustments.save}
          </button>
        </div>
      </div>

      <div className="ops-table-shell">
        <div className="ops-section-head">
          <div>
            <p className="ops-title">{dict.stockAdjustments.historyTitle}</p>
            <p className="ops-copy">{dict.stockAdjustments.historyCopy}</p>
          </div>
          <div className="ops-chip-muted">{items.length} adjustment</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.stockAdjustments.noData}</div>
        ) : (
          <div className="overflow-x-auto">
            <table className="ops-table">
              <thead>
                <tr>
                  <th>No</th>
                  <th>Lot</th>
                  <th>{dict.stockAdjustments.reason}</th>
                  <th>{dict.common.qty}</th>
                  <th>{dict.stockAdjustments.before}</th>
                  <th>{dict.stockAdjustments.after}</th>
                  <th>{dict.common.user}</th>
                </tr>
              </thead>
              <tbody>
                {items.map((item) => (
                  <tr key={item.id}>
                    <td className="font-semibold text-ink">{item.adjustment_no}</td>
                    <td>
                      <Link href={`/lots/${item.lot.id}`} className="font-medium text-ink underline-offset-4 hover:underline">
                        {item.lot.lot_code}
                      </Link>
                    </td>
                    <td className="text-slate-600">
                      {item.reason.name}
                      <div className="mt-1 text-xs text-slate-500">
                        {adjustmentReasonCategoryLabels[item.reason.category]}
                      </div>
                      {item.reason.description ? (
                        <div className="mt-1 text-xs leading-5 text-slate-500">
                          {item.reason.description}
                        </div>
                      ) : null}
                    </td>
                    <td className={item.qty_change < 0 ? "text-ember" : "text-moss"}>
                      {item.qty_change > 0 ? "+" : ""}
                      {formatQuantity(Math.abs(item.qty_change), locale, item.lot.unit_code)}
                    </td>
                    <td className="text-slate-600">{formatQuantity(item.available_qty_before, locale, item.lot.unit_code)}</td>
                    <td className="text-slate-600">{formatQuantity(item.available_qty_after, locale, item.lot.unit_code)}</td>
                    <td className="text-slate-600">
                      {item.created_by.name}
                      <div className="mt-1 text-xs text-slate-500">{item.created_by.role}</div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </section>
  );
}

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

function SelectField({
  label,
  value,
  onChange,
  options,
  placeholder
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  options: Array<{ value: string; label: string }>;
  placeholder: string;
}) {
  return (
    <label className="block">
      <span className="ops-label">{label}</span>
      <select
        value={value}
        onChange={(event) => onChange(event.target.value)}
        className="ops-select"
      >
        <option value="">{placeholder}</option>
        {options.map((option) => (
          <option key={`${label}-${option.value}`} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
    </label>
  );
}
