// AccountForm — variant=account (Issue #138 / Bilan #1a).
//
// The category variant lands in Issue #140 (Bilan #2) when the priced-kind
// switch becomes available. For now this component focuses on creating /
// editing a `balance_account` record bound to an existing category.

import { FormEvent, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import type {
  BalanceAccount,
  BalanceCategory,
} from "../../shared/types";
import type {
  CreateBalanceAccountInput,
  UpdateBalanceAccountInput,
} from "../../services/balance.service";

export interface AccountFormValues {
  balance_category_id: number;
  name: string;
  symbol: string;
  notes: string;
}

interface Props {
  /** When provided, the form is in edit mode; otherwise creation. */
  initialAccount?: BalanceAccount | null;
  categories: BalanceCategory[];
  isSaving: boolean;
  onSubmit: (
    values: CreateBalanceAccountInput | UpdateBalanceAccountInput
  ) => Promise<void> | void;
  onCancel: () => void;
}

function defaultValues(
  initial: BalanceAccount | null | undefined,
  categories: BalanceCategory[]
): AccountFormValues {
  if (initial) {
    return {
      balance_category_id: initial.balance_category_id,
      name: initial.name,
      symbol: initial.symbol ?? "",
      notes: initial.notes ?? "",
    };
  }
  // First active category as a sane default
  const first = categories.find((c) => c.is_active) ?? categories[0];
  return {
    balance_category_id: first?.id ?? 0,
    name: "",
    symbol: "",
    notes: "",
  };
}

export default function AccountForm({
  initialAccount,
  categories,
  isSaving,
  onSubmit,
  onCancel,
}: Props) {
  const { t } = useTranslation();
  const [values, setValues] = useState<AccountFormValues>(() =>
    defaultValues(initialAccount, categories)
  );
  const [touched, setTouched] = useState(false);

  // Reset form when target account changes (edit different row).
  useEffect(() => {
    setValues(defaultValues(initialAccount, categories));
    setTouched(false);
  }, [initialAccount, categories]);

  const isEditing = !!initialAccount;
  const selectedCategory = categories.find(
    (c) => c.id === values.balance_category_id
  );
  const isPriced = selectedCategory?.kind === "priced";
  const trimmedName = values.name.trim();
  const nameInvalid = touched && trimmedName.length === 0;

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();
    setTouched(true);
    if (!trimmedName) return;

    const payload: CreateBalanceAccountInput = {
      balance_category_id: values.balance_category_id,
      name: trimmedName,
      symbol: values.symbol.trim() || null,
      notes: values.notes.trim() || null,
    };

    if (isEditing) {
      const updatePayload: UpdateBalanceAccountInput = {
        balance_category_id: payload.balance_category_id,
        name: payload.name,
        symbol: payload.symbol,
        notes: payload.notes,
      };
      await onSubmit(updatePayload);
    } else {
      await onSubmit(payload);
    }
  };

  const renderCategoryLabel = (cat: BalanceCategory) =>
    t(cat.i18n_key, { defaultValue: cat.key });

  return (
    <form onSubmit={handleSubmit} className="flex flex-col gap-4">
      <div>
        <label className="block text-sm font-medium mb-1" htmlFor="account-category">
          {t("balance.account.form.category")}
        </label>
        <select
          id="account-category"
          value={values.balance_category_id}
          onChange={(e) =>
            setValues({
              ...values,
              balance_category_id: Number(e.target.value),
            })
          }
          className="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--card)] text-sm focus:outline-none focus:ring-1 focus:ring-[var(--primary)]"
        >
          {categories.length === 0 ? (
            <option value={0}>{t("balance.account.form.noCategory")}</option>
          ) : (
            categories.map((cat) => (
              <option key={cat.id} value={cat.id}>
                {renderCategoryLabel(cat)}
              </option>
            ))
          )}
        </select>
      </div>

      <div>
        <label className="block text-sm font-medium mb-1" htmlFor="account-name">
          {t("balance.account.form.name")}
        </label>
        <input
          id="account-name"
          type="text"
          value={values.name}
          onChange={(e) => setValues({ ...values, name: e.target.value })}
          onBlur={() => setTouched(true)}
          className={`w-full px-3 py-2 rounded-lg border bg-[var(--card)] text-sm focus:outline-none focus:ring-1 focus:ring-[var(--primary)] ${
            nameInvalid
              ? "border-[var(--negative)]"
              : "border-[var(--border)]"
          }`}
          autoFocus
          autoComplete="off"
        />
        {nameInvalid && (
          <p className="mt-1 text-xs text-[var(--negative)]">
            {t("balance.account.form.nameRequired")}
          </p>
        )}
      </div>

      <div>
        <label className="block text-sm font-medium mb-1" htmlFor="account-symbol">
          {t("balance.account.form.symbol")}
          {isPriced && (
            <span className="ml-1 text-xs text-[var(--muted-foreground)]">
              ({t("balance.account.form.symbolPricedHint")})
            </span>
          )}
        </label>
        <input
          id="account-symbol"
          type="text"
          value={values.symbol}
          onChange={(e) => setValues({ ...values, symbol: e.target.value })}
          placeholder={
            isPriced
              ? t("balance.account.form.symbolPlaceholderPriced")
              : t("balance.account.form.symbolPlaceholderSimple")
          }
          className="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--card)] text-sm focus:outline-none focus:ring-1 focus:ring-[var(--primary)]"
          autoComplete="off"
        />
      </div>

      <div>
        <label className="block text-sm font-medium mb-1" htmlFor="account-notes">
          {t("balance.account.form.notes")}
        </label>
        <textarea
          id="account-notes"
          value={values.notes}
          onChange={(e) => setValues({ ...values, notes: e.target.value })}
          rows={2}
          className="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--card)] text-sm focus:outline-none focus:ring-1 focus:ring-[var(--primary)] resize-none"
        />
      </div>

      <p className="text-xs text-[var(--muted-foreground)]">
        {t("balance.account.form.currencyMvpNotice")}
      </p>

      <div className="flex justify-end gap-2">
        <button
          type="button"
          onClick={onCancel}
          disabled={isSaving}
          className="px-4 py-2 rounded-lg border border-[var(--border)] text-sm hover:bg-[var(--muted)] disabled:opacity-50"
        >
          {t("common.cancel")}
        </button>
        <button
          type="submit"
          disabled={isSaving || !trimmedName || categories.length === 0}
          className="px-4 py-2 rounded-lg bg-[var(--primary)] text-white text-sm font-medium hover:opacity-90 disabled:opacity-50"
        >
          {isEditing
            ? t("balance.account.form.save")
            : t("balance.account.form.create")}
        </button>
      </div>
    </form>
  );
}
