'use client';

import { useEffect, useState } from 'react';
import { ChevronLeft, Pencil, Plus, Trash2 } from 'lucide-react';
import { useRouter } from 'next/navigation';

import MaterialForm, {
  MaterialFormState,
  MaterialTab,
} from '../_components/MaterialForm';
import Navbar from '@/components/Navbar';
import { api } from '@/lib/api';
import { Crop, Material } from '@/types';

const tabs: { key: MaterialTab; label: string }[] = [
  { key: 'fertilizer', label: '肥料' },
  { key: 'pesticide', label: '農薬' },
  { key: 'seed', label: '種子' },
  { key: 'misc', label: 'その他' },
];

const emptyForm = (tab: MaterialTab): MaterialFormState => ({
  name: '',
  material_type:
    tab === 'fertilizer'
      ? 'fertilizer'
      : tab === 'pesticide'
        ? 'pesticide'
        : tab === 'seed'
          ? 'seed'
          : 'other',
  seed_variety_id: '',
  maker: '',
  stock_unit:
    tab === 'fertilizer'
      ? 'bag'
      : tab === 'pesticide'
        ? 'bottle'
        : tab === 'seed'
          ? 'kg'
          : 'piece',
  is_active: true,
  notes: '',
  fertilizer_profile: {
    capacity_kg: '',
    nitrogen_pct: '',
    phosphorus_pct: '',
    potassium_pct: '',
  },
  pesticide_profile: {
    registration_no: '',
    formulation: '',
    usage_unit: '',
    dilution_ratio: '',
    active_ingredient: '',
    category: '',
  },
});

type VarietyOption = { id: number; label: string };

export default function MaterialMastersPage() {
  const router = useRouter();
  const [tab, setTab] = useState<MaterialTab>('fertilizer');
  const [materials, setMaterials] = useState<Material[]>([]);
  const [crops, setCrops] = useState<Crop[]>([]);
  const [loading, setLoading] = useState(true);
  const [editingId, setEditingId] = useState<number | 'new' | null>(null);
  const [form, setForm] = useState<MaterialFormState>(emptyForm('fertilizer'));
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    fetchData();
  }, []);

  useEffect(() => {
    if (editingId === 'new') {
      setForm(emptyForm(tab));
    }
  }, [tab, editingId]);

  const fetchData = async () => {
    setLoading(true);
    try {
      const [materialsRes, cropsRes] = await Promise.all([
        api.get('/materials/materials/'),
        api.get('/plans/crops/'),
      ]);
      setMaterials(materialsRes.data);
      setCrops(cropsRes.data);
    } catch (e) {
      console.error(e);
      setError('資材マスタの取得に失敗しました。');
    } finally {
      setLoading(false);
    }
  };

  const allVarieties = crops.flatMap((crop) =>
    crop.varieties.map((variety) => ({
      ...variety,
      crop_name: crop.name,
    }))
  );

  const seedVarietyOptions: VarietyOption[] = allVarieties.map((variety) => ({
    id: variety.id,
    label: `${variety.crop_name} / ${variety.name}`,
  }));

  const getLinkedVariety = (materialId: number) =>
    allVarieties.find((variety) => variety.seed_material === materialId) ?? null;

  const getLinkedVarietyLabel = (materialId: number) => {
    const variety = getLinkedVariety(materialId);
    return variety ? `${variety.crop_name} / ${variety.name}` : '-';
  };

  const visibleMaterials = materials.filter((material) => {
    if (tab === 'misc') {
      return material.material_type === 'other' || material.material_type === 'seedling';
    }
    return material.material_type === tab;
  });

  const startNew = () => {
    setError(null);
    setForm(emptyForm(tab));
    setEditingId('new');
  };

  const startEdit = (material: Material) => {
    setError(null);
    const linkedVariety = getLinkedVariety(material.id);
    setForm({
      name: material.name,
      material_type: material.material_type,
      seed_variety_id: linkedVariety ? String(linkedVariety.id) : '',
      maker: material.maker,
      stock_unit: material.stock_unit,
      is_active: material.is_active,
      notes: material.notes,
      fertilizer_profile: {
        capacity_kg: material.fertilizer_profile?.capacity_kg ?? '',
        nitrogen_pct: material.fertilizer_profile?.nitrogen_pct ?? '',
        phosphorus_pct: material.fertilizer_profile?.phosphorus_pct ?? '',
        potassium_pct: material.fertilizer_profile?.potassium_pct ?? '',
      },
      pesticide_profile: {
        registration_no: material.pesticide_profile?.registration_no ?? '',
        formulation: material.pesticide_profile?.formulation ?? '',
        usage_unit: material.pesticide_profile?.usage_unit ?? '',
        dilution_ratio: material.pesticide_profile?.dilution_ratio ?? '',
        active_ingredient: material.pesticide_profile?.active_ingredient ?? '',
        category: material.pesticide_profile?.category ?? '',
      },
    });
    setEditingId(material.id);
  };

  const cancelEdit = () => {
    setEditingId(null);
    setForm(emptyForm(tab));
  };

  const syncSeedVariety = async (materialId: number, seedVarietyId: string) => {
    const currentlyLinked = getLinkedVariety(materialId);
    const selectedVarietyId = seedVarietyId ? parseInt(seedVarietyId, 10) : null;

    if (currentlyLinked && currentlyLinked.id !== selectedVarietyId) {
      await api.patch(`/plans/varieties/${currentlyLinked.id}/`, {
        seed_material: null,
      });
    }

    if (selectedVarietyId) {
      await api.patch(`/plans/varieties/${selectedVarietyId}/`, {
        seed_material: materialId,
      });
    }
  };

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

    if (!form.name.trim()) {
      setError('資材名を入力してください。');
      return;
    }

    setSaving(true);
    try {
      const payload = {
        name: form.name,
        material_type: form.material_type,
        maker: form.maker,
        stock_unit: form.stock_unit,
        is_active: form.is_active,
        notes: form.notes,
        fertilizer_profile:
          form.material_type === 'fertilizer'
            ? {
                capacity_kg: form.fertilizer_profile.capacity_kg || null,
                nitrogen_pct: form.fertilizer_profile.nitrogen_pct || null,
                phosphorus_pct: form.fertilizer_profile.phosphorus_pct || null,
                potassium_pct: form.fertilizer_profile.potassium_pct || null,
              }
            : undefined,
        pesticide_profile:
          form.material_type === 'pesticide'
            ? {
                registration_no: form.pesticide_profile.registration_no,
                formulation: form.pesticide_profile.formulation,
                usage_unit: form.pesticide_profile.usage_unit,
                dilution_ratio: form.pesticide_profile.dilution_ratio,
                active_ingredient: form.pesticide_profile.active_ingredient,
                category: form.pesticide_profile.category,
              }
            : undefined,
      };

      let savedMaterial: Material;
      if (editingId === 'new') {
        const res = await api.post('/materials/materials/', payload);
        savedMaterial = res.data;
      } else {
        const res = await api.put(`/materials/materials/${editingId}/`, payload);
        savedMaterial = res.data;
      }

      if (form.material_type === 'seed') {
        await syncSeedVariety(savedMaterial.id, form.seed_variety_id);
      } else {
        const linkedVariety = getLinkedVariety(savedMaterial.id);
        if (linkedVariety) {
          await api.patch(`/plans/varieties/${linkedVariety.id}/`, {
            seed_material: null,
          });
        }
      }

      await fetchData();
      setEditingId(null);
      setForm(emptyForm(tab));
    } catch (e: unknown) {
      console.error(e);
      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);
    }
  };

  const handleDelete = async (material: Material) => {
    setError(null);
    try {
      await api.delete(`/materials/materials/${material.id}/`);
      await fetchData();
    } catch (e: unknown) {
      console.error(e);
      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)
          : `「${material.name}」の削除に失敗しました。`;
      setError(detail);
    }
  };

  const handleBaseFieldChange = (
    field: keyof Omit<MaterialFormState, 'fertilizer_profile' | 'pesticide_profile'>,
    value: string | boolean
  ) => {
    setForm((prev) => ({
      ...prev,
      [field]: value,
    }));
  };

  const handleFertilizerFieldChange = (
    field: keyof MaterialFormState['fertilizer_profile'],
    value: string
  ) => {
    setForm((prev) => ({
      ...prev,
      fertilizer_profile: {
        ...prev.fertilizer_profile,
        [field]: value,
      },
    }));
  };

  const handlePesticideFieldChange = (
    field: keyof MaterialFormState['pesticide_profile'],
    value: string
  ) => {
    setForm((prev) => ({
      ...prev,
      pesticide_profile: {
        ...prev.pesticide_profile,
        [field]: value,
      },
    }));
  };

  const tableProps = {
    materials: visibleMaterials,
    editingId,
    form,
    saving,
    seedVarietyOptions,
    getLinkedVarietyLabel,
    onEdit: startEdit,
    onDelete: handleDelete,
    onBaseFieldChange: handleBaseFieldChange,
    onFertilizerFieldChange: handleFertilizerFieldChange,
    onPesticideFieldChange: handlePesticideFieldChange,
    onSave: handleSave,
    onCancel: cancelEdit,
  };

  return (
    <div className="min-h-screen bg-gray-50">
      <Navbar />
      <div className="mx-auto max-w-7xl px-4 py-8">
        <div className="mb-6 flex items-center justify-between">
          <div className="flex items-center gap-3">
            <button
              onClick={() => router.push('/materials')}
              className="text-gray-500 transition hover:text-gray-700"
            >
              <ChevronLeft className="h-5 w-5" />
            </button>
            <div>
              <h1 className="text-2xl font-bold text-gray-800">資材マスタ管理</h1>
              <p className="text-sm text-gray-500">資材情報をインラインで編集できます。</p>
            </div>
          </div>
          <button
            onClick={startNew}
            disabled={editingId !== null}
            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-50"
          >
            <Plus className="h-4 w-4" />
            新規追加
          </button>
        </div>

        <div className="mb-5 flex flex-wrap gap-2">
          {tabs.map((item) => (
            <button
              key={item.key}
              onClick={() => {
                setTab(item.key);
                setEditingId(null);
                setForm(emptyForm(item.key));
              }}
              className={`rounded-full px-4 py-2 text-sm font-medium transition ${
                tab === item.key
                  ? 'bg-green-600 text-white shadow-sm'
                  : 'bg-white text-gray-600 hover:bg-gray-100'
              }`}
            >
              {item.label}
            </button>
          ))}
        </div>

        {error && (
          <div className="mb-4 flex items-start gap-2 rounded-xl border border-red-300 bg-red-50 px-4 py-3 text-sm text-red-700">
            <span>{error}</span>
            <button
              onClick={() => setError(null)}
              className="ml-auto text-red-400 transition hover:text-red-600"
            >
              ×
            </button>
          </div>
        )}

        {loading ? (
          <p className="text-sm text-gray-500">読み込み中...</p>
        ) : (
          <div className="overflow-x-auto rounded-2xl border border-gray-200 bg-white shadow-sm">
            {tab === 'fertilizer' && <FertilizerTable {...tableProps} />}
            {tab === 'pesticide' && <PesticideTable {...tableProps} />}
            {tab === 'seed' && <SeedTable {...tableProps} />}
            {tab === 'misc' && <MiscTable {...tableProps} />}
          </div>
        )}
      </div>
    </div>
  );
}

interface TableProps {
  materials: Material[];
  editingId: number | 'new' | null;
  form: MaterialFormState;
  saving: boolean;
  seedVarietyOptions: VarietyOption[];
  getLinkedVarietyLabel: (materialId: number) => string;
  onEdit: (material: Material) => void;
  onDelete: (material: Material) => void;
  onBaseFieldChange: (
    field: keyof Omit<MaterialFormState, 'fertilizer_profile' | 'pesticide_profile'>,
    value: string | boolean
  ) => void;
  onFertilizerFieldChange: (
    field: keyof MaterialFormState['fertilizer_profile'],
    value: string
  ) => void;
  onPesticideFieldChange: (
    field: keyof MaterialFormState['pesticide_profile'],
    value: string
  ) => void;
  onSave: () => void;
  onCancel: () => void;
}

function FertilizerTable(props: TableProps) {
  return (
    <table className="min-w-full text-sm">
      <thead className="bg-gray-50">
        <tr className="border-b border-gray-200">
          <th className="px-4 py-3 text-left font-medium text-gray-700">資材名</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">メーカー</th>
          <th className="px-4 py-3 text-right font-medium text-gray-700">1袋(kg)</th>
          <th className="px-4 py-3 text-right font-medium text-gray-700">窒素(%)</th>
          <th className="px-4 py-3 text-right font-medium text-gray-700">リン酸(%)</th>
          <th className="px-4 py-3 text-right font-medium text-gray-700">カリ(%)</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">単位</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">備考</th>
          <th className="px-4 py-3 text-center font-medium text-gray-700">使用中</th>
          <th className="px-4 py-3 text-right font-medium text-gray-700">操作</th>
        </tr>
      </thead>
      <tbody className="divide-y divide-gray-100">
        {props.editingId === 'new' && <MaterialForm tab="fertilizer" {...props} />}
        {props.materials.map((material) =>
          props.editingId === material.id ? (
            <MaterialForm key={material.id} tab="fertilizer" {...props} />
          ) : (
            <tr key={material.id} className="hover:bg-gray-50">
              <td className="px-4 py-3 font-medium text-gray-900">{material.name}</td>
              <td className="px-4 py-3 text-gray-600">{material.maker || '-'}</td>
              <td className="px-4 py-3 text-right text-gray-600">
                {material.fertilizer_profile?.capacity_kg ?? '-'}
              </td>
              <td className="px-4 py-3 text-right text-gray-600">
                {material.fertilizer_profile?.nitrogen_pct ?? '-'}
              </td>
              <td className="px-4 py-3 text-right text-gray-600">
                {material.fertilizer_profile?.phosphorus_pct ?? '-'}
              </td>
              <td className="px-4 py-3 text-right text-gray-600">
                {material.fertilizer_profile?.potassium_pct ?? '-'}
              </td>
              <td className="px-4 py-3 text-gray-600">{material.stock_unit_display}</td>
              <td className="max-w-xs px-4 py-3 text-gray-600">{material.notes || '-'}</td>
              <td className="px-4 py-3 text-center text-gray-600">
                {material.is_active ? '○' : '-'}
              </td>
              <td className="px-4 py-3">
                <RowActions
                  disabled={props.editingId !== null}
                  onEdit={() => props.onEdit(material)}
                  onDelete={() => props.onDelete(material)}
                />
              </td>
            </tr>
          )
        )}
        {props.materials.length === 0 && props.editingId === null && (
          <tr>
            <td colSpan={10} className="px-4 py-8 text-center text-gray-400">
              該当する資材が登録されていません
            </td>
          </tr>
        )}
      </tbody>
    </table>
  );
}

function PesticideTable(props: TableProps) {
  return (
    <table className="min-w-full text-sm">
      <thead className="bg-gray-50">
        <tr className="border-b border-gray-200">
          <th className="px-4 py-3 text-left font-medium text-gray-700">資材名</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">メーカー</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">登録番号</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">剤型</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">有効成分</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">分類</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">単位</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">備考</th>
          <th className="px-4 py-3 text-center font-medium text-gray-700">使用中</th>
          <th className="px-4 py-3 text-right font-medium text-gray-700">操作</th>
        </tr>
      </thead>
      <tbody className="divide-y divide-gray-100">
        {props.editingId === 'new' && <MaterialForm tab="pesticide" {...props} />}
        {props.materials.map((material) =>
          props.editingId === material.id ? (
            <MaterialForm key={material.id} tab="pesticide" {...props} />
          ) : (
            <tr key={material.id} className="hover:bg-gray-50">
              <td className="px-4 py-3 font-medium text-gray-900">{material.name}</td>
              <td className="px-4 py-3 text-gray-600">{material.maker || '-'}</td>
              <td className="px-4 py-3 text-gray-600">
                {material.pesticide_profile?.registration_no || '-'}
              </td>
              <td className="px-4 py-3 text-gray-600">
                {material.pesticide_profile?.formulation || '-'}
              </td>
              <td className="px-4 py-3 text-gray-600">
                {material.pesticide_profile?.active_ingredient || '-'}
              </td>
              <td className="px-4 py-3 text-gray-600">
                {material.pesticide_profile?.category || '-'}
              </td>
              <td className="px-4 py-3 text-gray-600">{material.stock_unit_display}</td>
              <td className="max-w-xs px-4 py-3 text-gray-600">{material.notes || '-'}</td>
              <td className="px-4 py-3 text-center text-gray-600">
                {material.is_active ? '○' : '-'}
              </td>
              <td className="px-4 py-3">
                <RowActions
                  disabled={props.editingId !== null}
                  onEdit={() => props.onEdit(material)}
                  onDelete={() => props.onDelete(material)}
                />
              </td>
            </tr>
          )
        )}
        {props.materials.length === 0 && props.editingId === null && (
          <tr>
            <td colSpan={10} className="px-4 py-8 text-center text-gray-400">
              該当する資材が登録されていません
            </td>
          </tr>
        )}
      </tbody>
    </table>
  );
}

function SeedTable(props: TableProps) {
  return (
    <table className="min-w-full text-sm">
      <thead className="bg-gray-50">
        <tr className="border-b border-gray-200">
          <th className="px-4 py-3 text-left font-medium text-gray-700">資材名</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">品種</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">メーカー</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">単位</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">備考</th>
          <th className="px-4 py-3 text-center font-medium text-gray-700">使用中</th>
          <th className="px-4 py-3 text-right font-medium text-gray-700">操作</th>
        </tr>
      </thead>
      <tbody className="divide-y divide-gray-100">
        {props.editingId === 'new' && <MaterialForm tab="seed" {...props} />}
        {props.materials.map((material) =>
          props.editingId === material.id ? (
            <MaterialForm key={material.id} tab="seed" {...props} />
          ) : (
            <tr key={material.id} className="hover:bg-gray-50">
              <td className="px-4 py-3 font-medium text-gray-900">{material.name}</td>
              <td className="px-4 py-3 text-gray-600">
                {props.getLinkedVarietyLabel(material.id)}
              </td>
              <td className="px-4 py-3 text-gray-600">{material.maker || '-'}</td>
              <td className="px-4 py-3 text-gray-600">{material.stock_unit_display}</td>
              <td className="max-w-xs px-4 py-3 text-gray-600">{material.notes || '-'}</td>
              <td className="px-4 py-3 text-center text-gray-600">
                {material.is_active ? '○' : '-'}
              </td>
              <td className="px-4 py-3">
                <RowActions
                  disabled={props.editingId !== null}
                  onEdit={() => props.onEdit(material)}
                  onDelete={() => props.onDelete(material)}
                />
              </td>
            </tr>
          )
        )}
        {props.materials.length === 0 && props.editingId === null && (
          <tr>
            <td colSpan={7} className="px-4 py-8 text-center text-gray-400">
              該当する資材が登録されていません
            </td>
          </tr>
        )}
      </tbody>
    </table>
  );
}

function MiscTable(props: TableProps) {
  return (
    <table className="min-w-full text-sm">
      <thead className="bg-gray-50">
        <tr className="border-b border-gray-200">
          <th className="px-4 py-3 text-left font-medium text-gray-700">資材名</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">種別</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">メーカー</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">単位</th>
          <th className="px-4 py-3 text-left font-medium text-gray-700">備考</th>
          <th className="px-4 py-3 text-center font-medium text-gray-700">使用中</th>
          <th className="px-4 py-3 text-right font-medium text-gray-700">操作</th>
        </tr>
      </thead>
      <tbody className="divide-y divide-gray-100">
        {props.editingId === 'new' && <MaterialForm tab="misc" {...props} />}
        {props.materials.map((material) =>
          props.editingId === material.id ? (
            <MaterialForm key={material.id} tab="misc" {...props} />
          ) : (
            <tr key={material.id} className="hover:bg-gray-50">
              <td className="px-4 py-3 font-medium text-gray-900">{material.name}</td>
              <td className="px-4 py-3 text-gray-600">{material.material_type_display}</td>
              <td className="px-4 py-3 text-gray-600">{material.maker || '-'}</td>
              <td className="px-4 py-3 text-gray-600">{material.stock_unit_display}</td>
              <td className="max-w-xs px-4 py-3 text-gray-600">{material.notes || '-'}</td>
              <td className="px-4 py-3 text-center text-gray-600">
                {material.is_active ? '○' : '-'}
              </td>
              <td className="px-4 py-3">
                <RowActions
                  disabled={props.editingId !== null}
                  onEdit={() => props.onEdit(material)}
                  onDelete={() => props.onDelete(material)}
                />
              </td>
            </tr>
          )
        )}
        {props.materials.length === 0 && props.editingId === null && (
          <tr>
            <td colSpan={7} className="px-4 py-8 text-center text-gray-400">
              該当する資材が登録されていません
            </td>
          </tr>
        )}
      </tbody>
    </table>
  );
}

function RowActions({
  disabled,
  onEdit,
  onDelete,
}: {
  disabled: boolean;
  onEdit: () => void;
  onDelete: () => void;
}) {
  return (
    <div className="flex items-center justify-end gap-2">
      <button
        onClick={onEdit}
        disabled={disabled}
        className="text-gray-400 transition hover:text-blue-600 disabled:opacity-30"
      >
        <Pencil className="h-4 w-4" />
      </button>
      <button
        onClick={onDelete}
        disabled={disabled}
        className="text-gray-400 transition hover:text-red-600 disabled:opacity-30"
      >
        <Trash2 className="h-4 w-4" />
      </button>
    </div>
  );
}
