"use client";

import { useEffect, useState } from "react";
import {
  Building2,
  Plus,
  Languages,
  Mail,
  Trash2,
  Save,
  Shield,
  Tags
} from "lucide-react";

import { useLocale } from "@/components/providers/locale-provider";
import type { BankRecord, CurrencyRecord } from "@/types/master-data";
import type { AppSettings } from "@/types/settings";

const timezoneOptions = ["Asia/Jakarta", "Asia/Makassar", "Asia/Jayapura"];
const dateFormatOptions = ["DD/MM/YYYY", "YYYY-MM-DD", "MM/DD/YYYY"];
const emptyCompanyBankAccount = () => ({
  bank_id: "",
  bank_code: "",
  bank_name: "",
  account_number: ""
});

function normalizeSettingsForm(settings: AppSettings): AppSettings {
  return {
    ...settings,
    company_bank_accounts:
      settings.company_bank_accounts.length > 0
        ? settings.company_bank_accounts
        : settings.company_bank_name || settings.company_bank_account_number
          ? [
              {
                bank_id: "",
                bank_code: "",
                bank_name: settings.company_bank_name,
                account_number: settings.company_bank_account_number
              }
            ]
          : [emptyCompanyBankAccount()]
  };
}

function Section({
  icon: Icon,
  title,
  copy,
  children,
  columnsClassName = "md:grid-cols-2"
}: {
  icon: typeof Building2;
  title: string;
  copy: string;
  children: React.ReactNode;
  columnsClassName?: string;
}) {
  return (
    <article className="ops-card p-6">
      <div className="flex items-start gap-3">
        <div className="rounded-lg bg-moss/10 p-3 text-moss">
          <Icon className="h-5 w-5" />
        </div>
        <div>
          <h2 className="text-lg font-semibold text-ink">{title}</h2>
          <p className="mt-2 text-[13px] leading-6 text-slate-600">{copy}</p>
        </div>
      </div>
      <div className={`mt-6 grid gap-4 ${columnsClassName}`}>{children}</div>
    </article>
  );
}

function Field({
  label,
  value,
  onChange,
  type = "text",
  placeholder,
  fullWidth = false
}: {
  label: string;
  value: string | number;
  onChange: (value: string) => void;
  type?: string;
  placeholder?: string;
  fullWidth?: boolean;
}) {
  return (
    <label className={fullWidth ? "md:col-span-2" : ""}>
      <span className="ops-label">{label}</span>
      {type === "textarea" ? (
        <textarea
          value={String(value)}
          onChange={(event) => onChange(event.target.value)}
          placeholder={placeholder}
          className="ops-input min-h-28"
        />
      ) : (
        <input
          type={type}
          value={String(value)}
          onChange={(event) => onChange(event.target.value)}
          placeholder={placeholder}
          className="ops-input"
        />
      )}
    </label>
  );
}

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

function CheckboxField({
  label,
  checked,
  onChange
}: {
  label: string;
  checked: boolean;
  onChange: (checked: boolean) => void;
}) {
  return (
    <label className="flex items-center gap-3 rounded border border-line/70 bg-slate-50 px-4 py-3">
      <input type="checkbox" checked={checked} onChange={(event) => onChange(event.target.checked)} />
      <span className="text-sm font-medium text-ink">{label}</span>
    </label>
  );
}

export function SettingsClient() {
  const { dict, locale } = useLocale();
  const [form, setForm] = useState<AppSettings | null>(null);
  const [currencyOptions, setCurrencyOptions] = useState<Array<{ value: string; label: string }>>([]);
  const [bankOptions, setBankOptions] = useState<Array<{ value: string; label: string }>>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    async function loadSettings() {
      setLoading(true);
      setError(null);

      try {
        const response = await fetch("/api/v1/settings", { cache: "no-store" });
        const payload = (await response.json()) as {
          data?: AppSettings;
          options?: { currencies?: CurrencyRecord[]; banks?: BankRecord[] };
          message?: string;
        };
        if (!response.ok || !payload.data) {
          throw new Error(payload.message ?? dict.settings.loadError);
        }
        setForm(normalizeSettingsForm(payload.data));
        setCurrencyOptions(
          (payload.options?.currencies ?? []).map((currency) => ({
            value: currency.code,
            label: `${currency.code} - ${currency.name}`
          }))
        );
        setBankOptions(
          (payload.options?.banks ?? []).map((bank) => ({
            value: bank.id,
            label: `${bank.code} - ${bank.name}`
          }))
        );
      } catch (err) {
        setError(err instanceof Error ? err.message : dict.settings.loadError);
      } finally {
        setLoading(false);
      }
    }

    void loadSettings();
  }, [dict.settings.loadError]);

  function update<K extends keyof AppSettings>(key: K, value: AppSettings[K]) {
    setForm((current) => (current ? { ...current, [key]: value } : current));
  }

  function updateCompanyBankAccount(index: number, patch: Partial<AppSettings["company_bank_accounts"][number]>) {
    setForm((current) =>
      current
        ? {
            ...current,
            company_bank_accounts: current.company_bank_accounts.map((account, itemIndex) =>
              itemIndex === index ? { ...account, ...patch } : account
            )
          }
        : current
    );
  }

  function addCompanyBankAccount() {
    setForm((current) =>
      current
        ? {
            ...current,
            company_bank_accounts: [...current.company_bank_accounts, emptyCompanyBankAccount()]
          }
        : current
    );
  }

  function removeCompanyBankAccount(index: number) {
    setForm((current) =>
      current
        ? {
            ...current,
            company_bank_accounts:
              current.company_bank_accounts.length === 1
                ? current.company_bank_accounts
                : current.company_bank_accounts.filter((_, itemIndex) => itemIndex !== index)
          }
        : current
    );
  }

  async function saveSettings() {
    if (!form) return;

    setSaving(true);
    setError(null);
    setMessage(null);

    try {
      const normalizedForm = {
        ...form,
        company_bank_accounts: form.company_bank_accounts.filter(
          (account) => account.bank_id.trim() || account.account_number.trim()
        )
      };
      const response = await fetch("/api/v1/settings", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(normalizedForm)
      });
      const payload = (await response.json()) as {
        data?: AppSettings;
        message?: string;
        errors?: Record<string, string[]>;
      };
      if (!response.ok || !payload.data) {
        const firstError = payload.errors ? Object.values(payload.errors)[0]?.[0] : undefined;
        throw new Error(firstError ?? payload.message ?? dict.settings.saveError);
      }

      const nextForm = normalizeSettingsForm(payload.data);
      setForm(nextForm);
      setMessage(payload.message ?? dict.settings.saveSuccess);
    } catch (err) {
      setError(err instanceof Error ? err.message : dict.settings.saveError);
    } finally {
      setSaving(false);
    }
  }

  if (loading || !form) {
    return <div className="ops-card p-6 text-sm text-slate-600">{dict.settings.loading}</div>;
  }

  return (
    <section className="space-y-6">
      <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
        <div>
          <p className="ops-title">{dict.settings.runtimeTitle}</p>
          <p className="mt-2 text-[14px] leading-7 text-slate-600">{dict.settings.runtimeCopy}</p>
        </div>
        <button type="button" onClick={() => void saveSettings()} disabled={saving} className="ops-btn-primary inline-flex items-center gap-2">
          <Save className="h-4 w-4" />
          {saving ? dict.common.processing : dict.settings.saveAll}
        </button>
      </div>

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

      <Section icon={Building2} title={dict.settings.company} copy={dict.settings.companyCopy}>
        <Field
          label={dict.settings.companyName}
          value={form.company_name}
          onChange={(value) => update("company_name", value)}
        />
        <Field
          label={dict.settings.companyEmail}
          value={form.company_email}
          onChange={(value) => update("company_email", value)}
          type="email"
        />
        <Field
          label={dict.settings.companyPhone}
          value={form.company_phone}
          onChange={(value) => update("company_phone", value)}
        />
        <SelectField
          label={dict.settings.companyTimezone}
          value={form.company_timezone}
          onChange={(value) => update("company_timezone", value)}
          options={timezoneOptions.map((option) => ({ value: option, label: option }))}
        />
        <Field
          label={dict.settings.companyAddress}
          value={form.company_address}
          onChange={(value) => update("company_address", value)}
          type="textarea"
          fullWidth
        />
        <div className="md:col-span-2">
          <div className="mb-3 flex items-center justify-between gap-3">
            <span className="ops-label !mb-0">{dict.settings.companyBankAccounts}</span>
            <button type="button" onClick={addCompanyBankAccount} className="ops-btn-secondary inline-flex items-center gap-2">
              <Plus className="h-4 w-4" />
              {dict.settings.addCompanyBankAccount}
            </button>
          </div>
          <div className="space-y-3">
            {(form.company_bank_accounts.length > 0 ? form.company_bank_accounts : [emptyCompanyBankAccount()]).map((account, index) => (
              <div key={`company-bank-${index}`} className="rounded border border-line/70 bg-slate-50/70 p-3">
                <div className="grid gap-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_52px]">
                  <SelectField
                    label={dict.settings.companyBankName}
                    value={account.bank_id}
                    onChange={(value) => {
                      const selectedBank = bankOptions.find((option) => option.value === value);
                      updateCompanyBankAccount(index, {
                        bank_id: value,
                        bank_name: selectedBank?.label.split(" - ").slice(1).join(" - ") ?? "",
                        bank_code: selectedBank?.label.split(" - ")[0] ?? ""
                      });
                    }}
                    options={[
                      {
                        value: "",
                        label: locale === "id" ? "Pilih bank perusahaan" : "Choose company bank"
                      },
                      ...bankOptions
                    ]}
                  />
                  <Field
                    label={dict.settings.companyBankAccountNumber}
                    value={account.account_number}
                    onChange={(value) => updateCompanyBankAccount(index, { account_number: value })}
                  />
                  <div className="flex items-end">
                    <button
                      type="button"
                      onClick={() => removeCompanyBankAccount(index)}
                      className="inline-flex h-[40px] w-[40px] items-center justify-center rounded border border-line/70 bg-white text-slate-500 transition hover:bg-slate-50 hover:text-ember disabled:opacity-40"
                      disabled={form.company_bank_accounts.length <= 1}
                      aria-label="Hapus rekening kantor"
                    >
                      <Trash2 className="h-4 w-4" />
                    </button>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </Section>

      <Section icon={Mail} title={dict.settings.email} copy={dict.settings.emailCopy}>
        <Field
          label={dict.settings.smtpHost}
          value={form.smtp_host}
          onChange={(value) => update("smtp_host", value)}
        />
        <Field
          label={dict.settings.smtpPort}
          value={form.smtp_port}
          onChange={(value) => update("smtp_port", Number(value || 0))}
          type="number"
        />
        <Field
          label={dict.settings.smtpUser}
          value={form.smtp_user}
          onChange={(value) => update("smtp_user", value)}
        />
        <Field
          label={dict.settings.smtpPassword}
          value={form.smtp_password}
          onChange={(value) => update("smtp_password", value)}
          type="password"
          placeholder={dict.settings.smtpPasswordPlaceholder}
        />
        <Field
          label={dict.settings.smtpFromName}
          value={form.smtp_from_name}
          onChange={(value) => update("smtp_from_name", value)}
        />
        <Field
          label={dict.settings.smtpFromEmail}
          value={form.smtp_from_email}
          onChange={(value) => update("smtp_from_email", value)}
          type="email"
        />
        <div className="md:col-span-2">
          <CheckboxField
            label={dict.settings.smtpSecure}
            checked={form.smtp_secure}
            onChange={(checked) => update("smtp_secure", checked)}
          />
        </div>
      </Section>

      <Section
        icon={Tags}
        title={dict.settings.numbering}
        copy={dict.settings.numberingCopy}
        columnsClassName="md:grid-cols-2 xl:grid-cols-3"
      >
        <Field
          label={dict.settings.purchasePrefix}
          value={form.purchase_prefix}
          onChange={(value) => update("purchase_prefix", value.toUpperCase())}
        />
        <Field
          label={dict.settings.receiptPrefix}
          value={form.receipt_prefix}
          onChange={(value) => update("receipt_prefix", value.toUpperCase())}
        />
        <Field
          label={dict.settings.lotPrefix}
          value={form.lot_prefix}
          onChange={(value) => update("lot_prefix", value.toUpperCase())}
        />
        <Field
          label={dict.settings.adjustmentPrefix}
          value={form.adjustment_prefix}
          onChange={(value) => update("adjustment_prefix", value.toUpperCase())}
        />
        <Field
          label={dict.settings.transformationPrefix}
          value={form.transformation_prefix}
          onChange={(value) => update("transformation_prefix", value.toUpperCase())}
        />
        <Field
          label={dict.settings.fundRequestPrefix}
          value={form.fund_request_prefix}
          onChange={(value) => update("fund_request_prefix", value.toUpperCase())}
        />
        <Field
          label={dict.settings.washingPrefix}
          value={form.washing_prefix}
          onChange={(value) => update("washing_prefix", value.toUpperCase())}
        />
        <Field
          label={dict.settings.regularSalePrefix}
          value={form.regular_sale_prefix}
          onChange={(value) => update("regular_sale_prefix", value.toUpperCase())}
        />
        <Field
          label={dict.settings.jitSalePrefix}
          value={form.jit_sale_prefix}
          onChange={(value) => update("jit_sale_prefix", value.toUpperCase())}
        />
        <Field
          label={dict.settings.consignmentPrefix}
          value={form.consignment_prefix}
          onChange={(value) => update("consignment_prefix", value.toUpperCase())}
        />
      </Section>

      <Section icon={Shield} title={dict.settings.security} copy={dict.settings.securityCopy}>
        <Field
          label={dict.settings.passwordMinLength}
          value={form.password_min_length}
          onChange={(value) => update("password_min_length", Number(value || 0))}
          type="number"
        />
        <Field
          label={dict.settings.sessionTimeoutMinutes}
          value={form.session_timeout_minutes}
          onChange={(value) => update("session_timeout_minutes", Number(value || 0))}
          type="number"
        />
        <Field
          label={dict.settings.auditRetentionDays}
          value={form.audit_retention_days}
          onChange={(value) => update("audit_retention_days", Number(value || 0))}
          type="number"
        />
        <div className="md:col-span-2">
          <CheckboxField
            label={dict.settings.requireEmailVerification}
            checked={form.require_email_verification}
            onChange={(checked) => update("require_email_verification", checked)}
          />
        </div>
      </Section>

      <Section icon={Languages} title={dict.settings.preferences} copy={dict.settings.preferencesCopy}>
        <label>
          <span className="ops-label">{dict.settings.defaultLanguage}</span>
          <select
            value={form.default_locale}
            onChange={(event) => update("default_locale", event.target.value as "id" | "en")}
            className="ops-input"
          >
            <option value="id">Bahasa Indonesia</option>
            <option value="en">English</option>
          </select>
        </label>
        <SelectField
          label={dict.settings.currencyCode}
          value={form.currency_code}
          onChange={(value) => update("currency_code", value)}
          options={
            currencyOptions.length > 0
              ? currencyOptions
              : [{ value: form.currency_code, label: form.currency_code }]
          }
        />
        <SelectField
          label={dict.settings.dateFormat}
          value={form.date_format}
          onChange={(value) => update("date_format", value)}
          options={dateFormatOptions.map((option) => ({ value: option, label: option }))}
        />
      </Section>
    </section>
  );
}
