'use client';

import { useEffect, useState } from 'react';
import { Loader2, X } from 'lucide-react';

import { api } from '@/lib/api';
import { Material, StockTransaction } from '@/types';

type TransactionType = StockTransaction['transaction_type'];

interface StockTransactionFormProps {
  isOpen: boolean;
  materials: Material[];
  presetMaterialId?: number | null;
  presetTransactionType?: TransactionType | null;
  editingTransaction?: StockTransaction | null;
  onClose: () => void;
  onSaved: () => Promise<void> | void;
}

const transactionOptions: { value: TransactionType; label: string }[] = [
  { value: 'purchase', label: '入庫' },
  { value: 'use', label: '使用' },
  { value: 'adjustment_plus', label: '棚卸増' },
  { value: 'adjustment_minus', label: '棚卸減' },
  { value: 'discard', label: '廃棄' },
];

const today = () => new Date().toISOString().slice(0, 10);

export default function StockTransactionForm({
  isOpen,
  materials,
  presetMaterialId = null,
  presetTransactionType = null,
  editingTransaction = null,
  onClose,
  onSaved,
}: StockTransactionFormProps) {
  const [materialId, setMaterialId] = useState<string>('');
  const [transactionType, setTransactionType] = useState<TransactionType>('purchase');
  const [quantity, setQuantity] = useState('');
  const [occurredOn, setOccurredOn] = useState(today());
  const [note, setNote] = useState('');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!isOpen) {
      return;
    }
    if (editingTransaction) {
      setMaterialId(String(editingTransaction.material));
      setTransactionType(editingTransaction.transaction_type);
      setQuantity(editingTransaction.quantity);
      setOccurredOn(editingTransaction.occurred_on);
      setNote(editingTransaction.note || '');
    } else {
      setMaterialId(presetMaterialId ? String(presetMaterialId) : '');
      setTransactionType(presetTransactionType ?? 'purchase');
      setQuantity('');
      setOccurredOn(today());
      setNote('');
    }
    setError(null);
  }, [isOpen, presetMaterialId, presetTransactionType, editingTransaction]);

  if (!isOpen) {
    return null;
  }

  const handleSave = async () => {
    setError(null);

    if (!materialId) {
      setError('資材を選択してください。');
      return;
    }
    if (!quantity || Number(quantity) <= 0) {
      setError('数量は0より大きい値を入力してください。');
      return;
    }

    setSaving(true);
    try {
      const payload = {
        material: Number(materialId),
        transaction_type: transactionType,
        quantity,
        occurred_on: occurredOn,
        note,
      };
      if (editingTransaction) {
        await api.put(`/materials/stock-transactions/${editingTransaction.id}/`, payload);
      } else {
        await api.post('/materials/stock-transactions/', payload);
      }
      await onSaved();
      onClose();
    } catch (e: unknown) {
      const detail =
        typeof e === 'object' &&
        e !== null &&
        'response' in e &&
        typeof e.response === 'object' &&
        e.response !== null &&
        'data' in e.response
          ? JSON.stringify(e.response.data)
          : '入出庫の登録に失敗しました。';
      setError(detail);
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-gray-900/40 px-4">
      <div className="w-full max-w-lg rounded-2xl bg-white shadow-2xl">
        <div className="flex items-center justify-between border-b border-gray-200 px-6 py-4">
          <div>
            <h2 className="text-lg font-semibold text-gray-900">入出庫登録</h2>
            <p className="text-sm text-gray-500">
              {editingTransaction ? '入出庫履歴を修正します。' : '在庫の増減を記録します。'}
            </p>
          </div>
          <button
            onClick={onClose}
            className="rounded-full p-2 text-gray-400 transition hover:bg-gray-100 hover:text-gray-600"
          >
            <X className="h-5 w-5" />
          </button>
        </div>

        <div className="space-y-4 px-6 py-5">
          {error && (
            <div className="rounded-lg border border-red-300 bg-red-50 px-4 py-3 text-sm text-red-700">
              {error}
            </div>
          )}

          <label className="block">
            <span className="mb-1 block text-sm font-medium text-gray-700">資材</span>
            <select
              value={materialId}
              onChange={(e) => setMaterialId(e.target.value)}
              className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-green-500 focus:outline-none focus:ring-2 focus:ring-green-200"
            >
              <option value="">選択してください</option>
              {materials.map((material) => (
                <option key={material.id} value={material.id}>
                  {material.name} ({material.material_type_display})
                </option>
              ))}
            </select>
          </label>

          <div className="grid gap-4 sm:grid-cols-2">
            <label className="block">
              <span className="mb-1 block text-sm font-medium text-gray-700">取引種別</span>
              <select
                value={transactionType}
                onChange={(e) => setTransactionType(e.target.value as TransactionType)}
                className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-green-500 focus:outline-none focus:ring-2 focus:ring-green-200"
              >
                {transactionOptions.map((option) => (
                  <option key={option.value} value={option.value}>
                    {option.label}
                  </option>
                ))}
              </select>
            </label>

            <label className="block">
              <span className="mb-1 block text-sm font-medium text-gray-700">数量</span>
              <input
                type="number"
                min="0"
                step="0.001"
                value={quantity}
                onChange={(e) => setQuantity(e.target.value)}
                className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-green-500 focus:outline-none focus:ring-2 focus:ring-green-200"
                placeholder="0.000"
              />
            </label>
          </div>

          <label className="block">
            <span className="mb-1 block text-sm font-medium text-gray-700">発生日</span>
            <input
              type="date"
              value={occurredOn}
              onChange={(e) => setOccurredOn(e.target.value)}
              className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-green-500 focus:outline-none focus:ring-2 focus:ring-green-200"
            />
          </label>

          <label className="block">
            <span className="mb-1 block text-sm font-medium text-gray-700">備考</span>
            <textarea
              value={note}
              onChange={(e) => setNote(e.target.value)}
              rows={3}
              className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-green-500 focus:outline-none focus:ring-2 focus:ring-green-200"
              placeholder="任意でメモを残せます"
            />
          </label>
        </div>

        <div className="flex justify-end gap-3 border-t border-gray-200 px-6 py-4">
          <button
            onClick={onClose}
            className="rounded-lg border border-gray-300 px-4 py-2 text-sm text-gray-700 transition hover:bg-gray-100"
          >
            キャンセル
          </button>
          <button
            onClick={handleSave}
            disabled={saving}
            className="inline-flex items-center gap-2 rounded-lg bg-green-600 px-4 py-2 text-sm font-medium text-white transition hover:bg-green-700 disabled:cursor-not-allowed disabled:opacity-60"
          >
            {saving && <Loader2 className="h-4 w-4 animate-spin" />}
            保存
          </button>
        </div>
      </div>
    </div>
  );
}
