'use client';

import { useEffect, useState, useMemo, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import { Plus, X, ChevronUp, ChevronDown, Pencil, Check, Truck, ArrowLeft, Sprout } from 'lucide-react';
import Navbar from '@/components/Navbar';
import { DeliveryPlan, DeliveryAllEntry } from '@/types';
import { api } from '@/lib/api';

const CURRENT_YEAR = new Date().getFullYear();

// ─── ローカル型定義 ──────────────────────────────────

interface LocalGroup {
  tempId: string;
  name: string;
  order: number;
  fieldIds: number[];
  isRenamingName?: string;
}

interface LocalTripItem {
  fieldId: number;
  fertilizerId: number;
  bags: number;
}

interface LocalTrip {
  tempId: string;
  order: number;
  name: string;
  date: string;
  items: LocalTripItem[];
}

interface FieldInfo {
  id: number;
  name: string;
  area_tan: string;
}

interface Props {
  planId?: number;
}

export default function DeliveryEditPage({ planId }: Props) {
  const router = useRouter();
  const isEdit = planId !== undefined;

  // 基本情報
  const [name, setName] = useState('');
  const [year, setYear] = useState<number>(() => {
    if (typeof window !== 'undefined') {
      return parseInt(localStorage.getItem('distributionYear') || String(CURRENT_YEAR), 10);
    }
    return CURRENT_YEAR;
  });

  // 施肥計画から取得した全エントリ（年度ベース）
  const [allEntries, setAllEntries] = useState<DeliveryAllEntry[]>([]);
  // 利用可能な肥料一覧
  const [availableFertilizers, setAvailableFertilizers] = useState<{ id: number; name: string }[]>([]);
  // 選択中の肥料ID
  const [selectedFertilizerIds, setSelectedFertilizerIds] = useState<Set<number>>(new Set());

  // ローカルグループ
  const [groups, setGroups] = useState<LocalGroup[]>([]);
  const [newGroupName, setNewGroupName] = useState('');

  // ローカルTrip
  const [trips, setTrips] = useState<LocalTrip[]>([]);

  // UI
  const [saveError, setSaveError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [loading, setLoading] = useState(true);

  const years = Array.from({ length: 5 }, (_, i) => CURRENT_YEAR + 1 - i);

  // ── 初期データ読み込み ──────────────────────────────────

  const loadYearEntries = useCallback(async (y: number) => {
    try {
      // 年度の全施肥計画のエントリを取得するために空のプランで詳細取得
      // → 新規時は計画がないので、施肥計画のエントリを直接取得する
      const plansRes = await api.get(`/fertilizer/plans/?year=${y}`);
      const plans = plansRes.data;
      const entries: DeliveryAllEntry[] = [];
      const fertMap = new Map<number, { id: number; name: string }>();
      for (const p of plans) {
        for (const e of p.entries) {
          entries.push({
            field: e.field,
            field_name: e.field_name || '',
            field_area_tan: e.field_area_tan || '0',
            fertilizer: e.fertilizer,
            fertilizer_name: e.fertilizer_name || '',
            bags: String(e.bags),
          });
          if (!fertMap.has(e.fertilizer)) {
            fertMap.set(e.fertilizer, { id: e.fertilizer, name: e.fertilizer_name || '' });
          }
        }
      }
      setAllEntries(entries);
      const ferts = Array.from(fertMap.values()).sort((a, b) => a.name.localeCompare(b.name));
      setAvailableFertilizers(ferts);
      return { entries, ferts };
    } catch (e) {
      console.error(e);
      return { entries: [], ferts: [] };
    }
  }, []);

  useEffect(() => {
    const init = async () => {
      if (isEdit && planId) {
        try {
          const detailRes = await api.get(`/fertilizer/delivery/${planId}/`);
          const detail: DeliveryPlan = detailRes.data;
          setName(detail.name);
          setYear(detail.year);
          setAllEntries(detail.all_entries);
          setAvailableFertilizers(detail.available_fertilizers);

          // グループを LocalGroup に変換
          setGroups(
            detail.groups.map((g, i) => ({
              tempId: String(g.id),
              name: g.name,
              order: g.order ?? i,
              fieldIds: g.fields.map(f => f.id),
            }))
          );

          // Trips を LocalTrip に変換
          setTrips(
            detail.trips.map(t => ({
              tempId: String(t.id),
              order: t.order,
              name: t.name,
              date: t.date || '',
              items: t.items.map(item => ({
                fieldId: item.field,
                fertilizerId: item.fertilizer,
                bags: parseFloat(item.bags),
              })),
            }))
          );

          // 選択肥料: tripに含まれる肥料 + 全部
          const usedFertIds = new Set<number>();
          for (const t of detail.trips) {
            for (const item of t.items) {
              usedFertIds.add(item.fertilizer);
            }
          }
          setSelectedFertilizerIds(
            usedFertIds.size > 0 ? usedFertIds : new Set(detail.available_fertilizers.map(f => f.id))
          );
        } catch (e) {
          console.error(e);
        }
      } else {
        const { ferts } = await loadYearEntries(year);
        setSelectedFertilizerIds(new Set(ferts.map(f => f.id)));
      }
      setLoading(false);
    };
    init();
  }, [planId]);

  // 年度変更時（新規のみ）
  useEffect(() => {
    if (!isEdit && !loading) {
      loadYearEntries(year).then(({ ferts }) => {
        setSelectedFertilizerIds(new Set(ferts.map(f => f.id)));
        setGroups([]);
        setTrips([]);
      });
    }
  }, [year, isEdit, loading, loadYearEntries]);

  // ── 計算ヘルパー ──────────────────────────────────────

  // 圃場情報マップ
  const fieldInfoMap = useMemo(() => {
    const map = new Map<number, FieldInfo>();
    for (const e of allEntries) {
      if (!map.has(e.field)) {
        map.set(e.field, { id: e.field, name: e.field_name, area_tan: e.field_area_tan });
      }
    }
    return map;
  }, [allEntries]);

  const getFieldInfo = useCallback((fieldId: number): FieldInfo =>
    fieldInfoMap.get(fieldId) ?? { id: fieldId, name: `圃場#${fieldId}`, area_tan: '0' },
    [fieldInfoMap]
  );

  // 選択中の肥料
  const selectedFertilizers = useMemo(
    () => availableFertilizers.filter(f => selectedFertilizerIds.has(f.id)),
    [availableFertilizers, selectedFertilizerIds]
  );

  // (field, fertilizer) → bags マップ（施肥計画ベース）
  const entryBagsMap = useMemo(() => {
    const map = new Map<string, number>();
    for (const e of allEntries) {
      const key = `${e.field}-${e.fertilizer}`;
      map.set(key, (map.get(key) || 0) + parseFloat(e.bags));
    }
    return map;
  }, [allEntries]);

  const getPlannedBags = useCallback((fieldId: number, fertilizerId: number): number => {
    return entryBagsMap.get(`${fieldId}-${fertilizerId}`) || 0;
  }, [entryBagsMap]);

  // 全グループの全圃場ID
  const allGroupFieldIds = useMemo(
    () => new Set(groups.flatMap(g => g.fieldIds)),
    [groups]
  );

  // グループに属する圃場 × 選択肥料 で実際にエントリがある圃場
  const relevantFieldIds = useMemo(() => {
    const ids = new Set<number>();
    for (const e of allEntries) {
      if (selectedFertilizerIds.has(e.fertilizer)) {
        ids.add(e.field);
      }
    }
    return ids;
  }, [allEntries, selectedFertilizerIds]);

  // 未割り当て圃場（グループに入っていない + 選択肥料のエントリがある）
  const unassignedFields = useMemo(() => {
    const result: FieldInfo[] = [];
    for (const fId of Array.from(relevantFieldIds)) {
      if (!allGroupFieldIds.has(fId)) {
        result.push(getFieldInfo(fId));
      }
    }
    return result.sort((a, b) => a.name.localeCompare(b.name));
  }, [relevantFieldIds, allGroupFieldIds, getFieldInfo]);

  // tripに割り当て済みの (field, fertilizer) → 合計bags
  const assignedBagsMap = useMemo(() => {
    const map = new Map<string, number>();
    for (const trip of trips) {
      for (const item of trip.items) {
        const key = `${item.fieldId}-${item.fertilizerId}`;
        map.set(key, (map.get(key) || 0) + item.bags);
      }
    }
    return map;
  }, [trips]);

  // 未割り当てのbags（施肥計画の合計 - 既にtripに割り当て済み）
  const getUnassignedBags = useCallback((fieldId: number, fertilizerId: number): number => {
    const planned = getPlannedBags(fieldId, fertilizerId);
    const assigned = assignedBagsMap.get(`${fieldId}-${fertilizerId}`) || 0;
    return Math.max(0, planned - assigned);
  }, [getPlannedBags, assignedBagsMap]);

  // trip積載合計
  const getTripTotal = useCallback((trip: LocalTrip): number => {
    return trip.items.reduce((sum, item) => sum + item.bags, 0);
  }, []);

  // tripの肥料ごと合計
  const getTripFertTotal = useCallback((trip: LocalTrip, fertilizerId: number): number => {
    return trip.items
      .filter(item => item.fertilizerId === fertilizerId)
      .reduce((sum, item) => sum + item.bags, 0);
  }, []);

  // ── グループ操作 ──────────────────────────────────────

  const addGroup = () => {
    const n = newGroupName.trim();
    if (!n) return;
    if (groups.some(g => g.name === n)) {
      setSaveError(`グループ名「${n}」はすでに存在します`);
      return;
    }
    setSaveError(null);
    setGroups(prev => [
      ...prev,
      { tempId: crypto.randomUUID(), name: n, order: prev.length, fieldIds: [] },
    ]);
    setNewGroupName('');
  };

  const removeGroup = (tempId: string) => {
    setGroups(prev => prev.filter(g => g.tempId !== tempId));
  };

  const moveGroup = (tempId: string, dir: -1 | 1) => {
    setGroups(prev => {
      const idx = prev.findIndex(g => g.tempId === tempId);
      if (idx < 0 || idx + dir < 0 || idx + dir >= prev.length) return prev;
      const next = [...prev];
      [next[idx], next[idx + dir]] = [next[idx + dir], next[idx]];
      return next.map((g, i) => ({ ...g, order: i }));
    });
  };

  const startRename = (tempId: string) => {
    setGroups(prev =>
      prev.map(g => (g.tempId === tempId ? { ...g, isRenamingName: g.name } : g))
    );
  };

  const commitRename = (tempId: string) => {
    setGroups(prev =>
      prev.map(g => {
        if (g.tempId !== tempId) return g;
        const newName = (g.isRenamingName || '').trim();
        if (!newName || newName === g.name) return { ...g, isRenamingName: undefined };
        if (prev.some(other => other.tempId !== tempId && other.name === newName)) {
          setSaveError(`グループ名「${newName}」はすでに存在します`);
          return { ...g, isRenamingName: undefined };
        }
        return { ...g, name: newName, isRenamingName: undefined };
      })
    );
  };

  const assignFieldToGroup = (fieldId: number, groupTempId: string) => {
    setGroups(prev =>
      prev.map(g => {
        if (g.tempId === groupTempId) {
          return { ...g, fieldIds: [...g.fieldIds, fieldId] };
        }
        return { ...g, fieldIds: g.fieldIds.filter(id => id !== fieldId) };
      })
    );
  };

  const removeFieldFromGroup = (fieldId: number, groupTempId: string) => {
    setGroups(prev =>
      prev.map(g =>
        g.tempId === groupTempId ? { ...g, fieldIds: g.fieldIds.filter(id => id !== fieldId) } : g
      )
    );
  };

  // ── Trip操作 ──────────────────────────────────────

  const addTrip = () => {
    const defaultDate = trips.length > 0 ? trips[0].date : '';
    setTrips(prev => [
      ...prev,
      { tempId: crypto.randomUUID(), order: prev.length, name: '', date: defaultDate, items: [] },
    ]);
  };

  const removeTrip = (tempId: string) => {
    setTrips(prev => prev.filter(t => t.tempId !== tempId));
  };

  const updateTripName = (tempId: string, name: string) => {
    setTrips(prev => prev.map(t => t.tempId === tempId ? { ...t, name } : t));
  };

  const updateTripDate = (tempId: string, date: string) => {
    setTrips(prev => prev.map(t => t.tempId === tempId ? { ...t, date } : t));
  };

  // 圃場をtripに割り当て（その圃場の選択肥料の未割り当て分全部）
  const assignFieldToTrip = (fieldId: number, tripTempId: string) => {
    setTrips(prev => prev.map(t => {
      if (t.tempId !== tripTempId) return t;
      const newItems = [...t.items];
      for (const fert of selectedFertilizers) {
        const remaining = getUnassignedBags(fieldId, fert.id);
        if (remaining > 0) {
          // 既に同じ field+fertilizer がこのtripにあれば加算
          const existing = newItems.find(
            item => item.fieldId === fieldId && item.fertilizerId === fert.id
          );
          if (existing) {
            existing.bags += remaining;
          } else {
            newItems.push({ fieldId, fertilizerId: fert.id, bags: remaining });
          }
        }
      }
      return { ...t, items: newItems };
    }));
  };

  // 圃場をtripから外す（その圃場の全肥料をtripから削除）
  const removeFieldFromTrip = (fieldId: number, tripTempId: string) => {
    setTrips(prev => prev.map(t => {
      if (t.tempId !== tripTempId) return t;
      return { ...t, items: t.items.filter(item => item.fieldId !== fieldId) };
    }));
  };

  // 残り全部を新しいtripに
  const assignAllRemaining = () => {
    const items: LocalTripItem[] = [];
    // グループ内の圃場を順に
    for (const group of groups) {
      for (const fieldId of group.fieldIds) {
        for (const fert of selectedFertilizers) {
          const remaining = getUnassignedBags(fieldId, fert.id);
          if (remaining > 0) {
            items.push({ fieldId, fertilizerId: fert.id, bags: remaining });
          }
        }
      }
    }
    // 未割り当て圃場も
    for (const fi of unassignedFields) {
      for (const fert of selectedFertilizers) {
        const remaining = getUnassignedBags(fi.id, fert.id);
        if (remaining > 0) {
          items.push({ fieldId: fi.id, fertilizerId: fert.id, bags: remaining });
        }
      }
    }
    if (items.length === 0) return;
    const defaultDate = trips.length > 0 ? trips[0].date : '';
    setTrips(prev => [
      ...prev,
      { tempId: crypto.randomUUID(), order: prev.length, name: '', date: defaultDate, items },
    ]);
  };

  // グループの全圃場をtripに一括割り当て
  const assignGroupToTrip = (groupTempId: string, tripTempId: string) => {
    const group = groups.find(g => g.tempId === groupTempId);
    if (!group) return;
    setTrips(prev => prev.map(t => {
      if (t.tempId !== tripTempId) return t;
      const newItems = [...t.items];
      for (const fieldId of group.fieldIds) {
        for (const fert of selectedFertilizers) {
          const remaining = getUnassignedBags(fieldId, fert.id);
          if (remaining > 0) {
            const existing = newItems.find(
              item => item.fieldId === fieldId && item.fertilizerId === fert.id
            );
            if (existing) {
              existing.bags += remaining;
            } else {
              newItems.push({ fieldId, fertilizerId: fert.id, bags: remaining });
            }
          }
        }
      }
      return { ...t, items: newItems };
    }));
  };

  // tripの中の圃場IDを取得（表示用・重複なし）
  const getTripFieldIds = useCallback((trip: LocalTrip): number[] => {
    const seen = new Set<number>();
    const result: number[] = [];
    for (const item of trip.items) {
      if (!seen.has(item.fieldId)) {
        seen.add(item.fieldId);
        result.push(item.fieldId);
      }
    }
    return result;
  }, []);

  // tripの中の圃場をグループでまとめる
  const getTripGroupedFields = useCallback((trip: LocalTrip) => {
    const fieldIds = getTripFieldIds(trip);
    const fieldGroupMap = new Map<number, string>(); // fieldId → groupName
    for (const g of groups) {
      for (const fId of g.fieldIds) {
        fieldGroupMap.set(fId, g.name);
      }
    }

    const groupedMap = new Map<string, number[]>(); // groupName → fieldIds
    const ungrouped: number[] = [];

    for (const fId of fieldIds) {
      const groupName = fieldGroupMap.get(fId);
      if (groupName) {
        if (!groupedMap.has(groupName)) groupedMap.set(groupName, []);
        groupedMap.get(groupName)!.push(fId);
      } else {
        ungrouped.push(fId);
      }
    }

    // groups の order 順で返す
    const result: { groupName: string; fieldIds: number[] }[] = [];
    for (const g of groups) {
      if (groupedMap.has(g.name)) {
        result.push({ groupName: g.name, fieldIds: groupedMap.get(g.name)! });
      }
    }
    if (ungrouped.length > 0) {
      result.push({ groupName: '未グループ', fieldIds: ungrouped });
    }
    return result;
  }, [groups, getTripFieldIds]);

  // 圃場を別のtripに移動（元のtripから削除して移動先に追加）
  const moveFieldToTrip = (fieldId: number, fromTripTempId: string, toTripTempId: string) => {
    setTrips(prev => {
      // 元のtripからこの圃場のitemsを取り出す
      const fromTrip = prev.find(t => t.tempId === fromTripTempId);
      if (!fromTrip) return prev;
      const movingItems = fromTrip.items.filter(item => item.fieldId === fieldId);
      if (movingItems.length === 0) return prev;

      return prev.map(t => {
        if (t.tempId === fromTripTempId) {
          // 元のtripから削除
          return { ...t, items: t.items.filter(item => item.fieldId !== fieldId) };
        }
        if (t.tempId === toTripTempId) {
          // 移動先に追加（同じfield+fertilizerがあれば加算）
          const newItems = [...t.items];
          for (const moving of movingItems) {
            const existing = newItems.find(
              item => item.fieldId === moving.fieldId && item.fertilizerId === moving.fertilizerId
            );
            if (existing) {
              existing.bags += moving.bags;
            } else {
              newItems.push({ ...moving });
            }
          }
          return { ...t, items: newItems };
        }
        return t;
      });
    });
  };

  // 圃場をtripから未割り当てに戻す
  const returnFieldToUnassigned = (fieldId: number, tripTempId: string) => {
    removeFieldFromTrip(fieldId, tripTempId);
  };

  // グループの全圃場を別のtripに移動
  const moveGroupToTrip = (groupFieldIds: number[], fromTripTempId: string, toTripTempId: string) => {
    setTrips(prev => {
      const fromTrip = prev.find(t => t.tempId === fromTripTempId);
      if (!fromTrip) return prev;
      const fieldIdSet = new Set(groupFieldIds);
      const movingItems = fromTrip.items.filter(item => fieldIdSet.has(item.fieldId));
      if (movingItems.length === 0) return prev;

      return prev.map(t => {
        if (t.tempId === fromTripTempId) {
          return { ...t, items: t.items.filter(item => !fieldIdSet.has(item.fieldId)) };
        }
        if (t.tempId === toTripTempId) {
          const newItems = [...t.items];
          for (const moving of movingItems) {
            const existing = newItems.find(
              item => item.fieldId === moving.fieldId && item.fertilizerId === moving.fertilizerId
            );
            if (existing) {
              existing.bags += moving.bags;
            } else {
              newItems.push({ ...moving });
            }
          }
          return { ...t, items: newItems };
        }
        return t;
      });
    });
  };

  // グループの全圃場をtripから未割り当てに戻す
  const returnGroupToUnassigned = (groupFieldIds: number[], tripTempId: string) => {
    const fieldIdSet = new Set(groupFieldIds);
    setTrips(prev => prev.map(t => {
      if (t.tempId !== tripTempId) return t;
      return { ...t, items: t.items.filter(item => !fieldIdSet.has(item.fieldId)) };
    }));
  };

  // tripのグループ小計
  const getTripGroupFertTotal = useCallback((trip: LocalTrip, fieldIds: number[], fertilizerId: number): number => {
    return trip.items
      .filter(item => fieldIds.includes(item.fieldId) && item.fertilizerId === fertilizerId)
      .reduce((sum, item) => sum + item.bags, 0);
  }, []);

  // ── 保存 ──────────────────────────────────────────────

  const handleSave = async () => {
    setSaveError(null);
    if (!name.trim()) { setSaveError('計画名を入力してください'); return; }

    setSaving(true);
    const payload = {
      year,
      name: name.trim(),
      groups: groups.map((g, i) => ({
        name: g.name,
        order: i,
        field_ids: g.fieldIds,
      })),
      trips: trips.map((t, i) => ({
        order: i,
        name: t.name,
        date: t.date || null,
        items: t.items.map(item => ({
          field_id: item.fieldId,
          fertilizer_id: item.fertilizerId,
          bags: item.bags.toFixed(4),
        })),
      })),
    };

    try {
      if (isEdit) {
        await api.put(`/fertilizer/delivery/${planId}/`, payload);
      } else {
        await api.post('/fertilizer/delivery/', payload);
      }
      setSaving(false);
      router.push('/distribution');
    } catch (e: unknown) {
      setSaving(false);
      const axiosErr = e as { response?: { data?: unknown } };
      const errData = axiosErr?.response?.data;
      setSaveError(errData ? JSON.stringify(errData) : '保存に失敗しました');
    }
  };

  // ── レンダリング ──────────────────────────────────────

  if (loading) {
    return (
      <div className="min-h-screen bg-gray-50">
        <Navbar />
        <main className="max-w-6xl mx-auto px-4 py-8 text-gray-500 text-sm">読み込み中...</main>
      </div>
    );
  }

  // 未割り当てのtripに入っていない圃場×肥料があるか
  const hasUnassignedBags = (() => {
    for (const g of groups) {
      for (const fId of g.fieldIds) {
        for (const fert of selectedFertilizers) {
          if (getUnassignedBags(fId, fert.id) > 0) return true;
        }
      }
    }
    for (const fi of unassignedFields) {
      for (const fert of selectedFertilizers) {
        if (getUnassignedBags(fi.id, fert.id) > 0) return true;
      }
    }
    return false;
  })();

  return (
    <div className="min-h-screen bg-gray-50">
      <Navbar />
      <main className="max-w-6xl mx-auto px-4 py-8">
        {/* ヘッダー */}
        <button onClick={() => router.push('/distribution')} className="flex items-center gap-1 text-sm text-gray-500 hover:text-gray-700 mb-4">
          <ArrowLeft className="h-4 w-4" />
          運搬計画一覧
        </button>

        <div className="mb-6 flex items-center justify-between gap-4">
          <h1 className="text-xl font-bold text-gray-900">
            {isEdit ? '運搬計画を編集' : '運搬計画を新規作成'}
          </h1>
          {isEdit && planId && (
            <button
              onClick={() => router.push(`/fertilizer/spreading?year=${year}&delivery_plan=${planId}`)}
              className="flex items-center gap-2 rounded-md border border-emerald-300 px-4 py-2 text-sm text-emerald-700 hover:bg-emerald-50"
            >
              <Sprout className="h-4 w-4" />
              この運搬計画から散布実績へ進む
            </button>
          )}
        </div>

        {saveError && (
          <div className="flex items-start gap-2 bg-red-50 border border-red-300 text-red-700 rounded-md px-4 py-3 mb-4 text-sm">
            <span className="flex-1">{saveError}</span>
            <button onClick={() => setSaveError(null)}><X className="h-4 w-4" /></button>
          </div>
        )}

        {/* 基本情報 */}
        <div className="bg-white rounded-lg border border-gray-200 p-4 mb-6">
          <div className="flex flex-wrap items-center gap-4">
            <div className="flex items-center gap-2 flex-1 min-w-48">
              <label className="text-sm font-medium text-gray-700 whitespace-nowrap">計画名</label>
              <input
                type="text"
                value={name}
                onChange={e => setName(e.target.value)}
                placeholder="例: 2026春 肥料運搬"
                className="flex-1 border border-gray-300 rounded-md px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-green-500"
              />
            </div>
            <div className="flex items-center gap-2">
              <label className="text-sm font-medium text-gray-700 whitespace-nowrap">年度</label>
              <select
                value={year}
                onChange={e => setYear(Number(e.target.value))}
                disabled={isEdit}
                className="border border-gray-300 rounded-md px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-green-500 disabled:bg-gray-100"
              >
                {years.map(y => (
                  <option key={y} value={y}>{y}年</option>
                ))}
              </select>
            </div>
          </div>
        </div>

        {allEntries.length === 0 ? (
          <div className="bg-white rounded-lg border border-gray-200 p-8 text-center text-gray-400 text-sm">
            {year}年の施肥計画がありません。先に施肥計画を作成してください。
          </div>
        ) : (
          <>
            {/* 対象肥料チェックボックス */}
            <div className="bg-white rounded-lg border border-gray-200 p-4 mb-6">
              <h2 className="text-sm font-semibold text-gray-700 mb-3">対象肥料</h2>
              <div className="flex flex-wrap gap-3">
                {availableFertilizers.map(fert => (
                  <label key={fert.id} className="flex items-center gap-1.5 text-sm cursor-pointer">
                    <input
                      type="checkbox"
                      checked={selectedFertilizerIds.has(fert.id)}
                      onChange={e => {
                        setSelectedFertilizerIds(prev => {
                          const next = new Set(prev);
                          if (e.target.checked) next.add(fert.id);
                          else next.delete(fert.id);
                          return next;
                        });
                      }}
                      className="rounded border-gray-300 text-green-600 focus:ring-green-500"
                    />
                    {fert.name}
                  </label>
                ))}
              </div>
            </div>

            {/* グループ定義 */}
            <div className="bg-white rounded-lg border border-gray-200 p-4 mb-6">
              <h2 className="text-sm font-semibold text-gray-700 mb-4">グループ定義</h2>

              {/* 新規グループ追加 */}
              <div className="flex items-center gap-2 mb-4">
                <input
                  type="text"
                  value={newGroupName}
                  onChange={e => setNewGroupName(e.target.value)}
                  onKeyDown={e => e.key === 'Enter' && addGroup()}
                  placeholder="新規グループ名"
                  className="border border-gray-300 rounded-md px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-green-500 w-48"
                />
                <button
                  onClick={addGroup}
                  className="flex items-center gap-1 px-3 py-1.5 bg-green-600 text-white text-sm rounded-md hover:bg-green-700"
                >
                  <Plus className="h-4 w-4" />
                  グループを追加
                </button>
              </div>

              {/* グループ一覧 */}
              <div className="space-y-3">
                {groups.map((group, idx) => (
                  <div key={group.tempId} className="border border-gray-200 rounded-md overflow-hidden">
                    <div className="flex items-center gap-2 bg-green-50 px-3 py-2">
                      {group.isRenamingName !== undefined ? (
                        <>
                          <input
                            type="text"
                            value={group.isRenamingName}
                            onChange={e =>
                              setGroups(prev =>
                                prev.map(g =>
                                  g.tempId === group.tempId ? { ...g, isRenamingName: e.target.value } : g
                                )
                              )
                            }
                            onKeyDown={e => e.key === 'Enter' && commitRename(group.tempId)}
                            className="flex-1 border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-green-500"
                            autoFocus
                          />
                          <button onClick={() => commitRename(group.tempId)} className="p-1 text-green-700 hover:text-green-900">
                            <Check className="h-4 w-4" />
                          </button>
                        </>
                      ) : (
                        <>
                          <span className="font-medium text-sm text-gray-800 flex-1">{group.name}</span>
                          <span className="text-xs text-gray-400">{group.fieldIds.length}圃場</span>
                          <button onClick={() => moveGroup(group.tempId, -1)} disabled={idx === 0} className="p-1 text-gray-400 hover:text-gray-600 disabled:opacity-30">
                            <ChevronUp className="h-4 w-4" />
                          </button>
                          <button onClick={() => moveGroup(group.tempId, 1)} disabled={idx === groups.length - 1} className="p-1 text-gray-400 hover:text-gray-600 disabled:opacity-30">
                            <ChevronDown className="h-4 w-4" />
                          </button>
                          <button onClick={() => startRename(group.tempId)} className="p-1 text-gray-400 hover:text-gray-600" title="名前変更">
                            <Pencil className="h-4 w-4" />
                          </button>
                          <button onClick={() => removeGroup(group.tempId)} className="p-1 text-gray-400 hover:text-red-600" title="グループを削除">
                            <X className="h-4 w-4" />
                          </button>
                        </>
                      )}
                    </div>
                    <div className="px-3 py-2 space-y-1">
                      {group.fieldIds.length === 0 ? (
                        <p className="text-xs text-gray-400 italic">圃場が割り当てられていません</p>
                      ) : (
                        group.fieldIds.map(fId => {
                          const fi = getFieldInfo(fId);
                          return (
                            <div key={fId} className="flex items-center gap-2 text-sm">
                              <button
                                onClick={() => removeFieldFromGroup(fId, group.tempId)}
                                className="text-gray-400 hover:text-red-500 flex-shrink-0"
                              >
                                <X className="h-3.5 w-3.5" />
                              </button>
                              <span className="text-gray-800 font-medium w-32 truncate">{fi.name}</span>
                              <span className="text-gray-400 text-xs">
                                {selectedFertilizers.map((fert, i) => {
                                  const bags = getPlannedBags(fId, fert.id);
                                  if (bags === 0) return null;
                                  return (
                                    <span key={fert.id}>
                                      {i > 0 && ' / '}
                                      {fert.name}: {bags.toFixed(2)}
                                    </span>
                                  );
                                })}
                              </span>
                            </div>
                          );
                        })
                      )}
                    </div>
                  </div>
                ))}
              </div>

              {/* 未割り当て圃場 */}
              {unassignedFields.length > 0 && (
                <div className="mt-4 border-t border-gray-200 pt-4">
                  <p className="text-xs font-medium text-gray-500 uppercase mb-2">未割り当て圃場</p>
                  <div className="rounded border border-gray-200 overflow-hidden">
                    {unassignedFields.map((fi, idx) => (
                      <div key={fi.id} className={`flex items-center gap-2 text-sm px-3 py-1.5 ${idx % 2 === 0 ? 'bg-white' : 'bg-gray-50'}`}>
                        <span className="text-gray-800 font-medium flex-1 min-w-0 truncate">{fi.name}</span>
                        <select
                          defaultValue=""
                          onChange={e => {
                            if (e.target.value) {
                              assignFieldToGroup(fi.id, e.target.value);
                              e.target.value = '';
                            }
                          }}
                          className="border border-gray-300 rounded px-2 py-1 text-xs focus:outline-none focus:ring-1 focus:ring-green-500"
                        >
                          <option value="">グループに追加...</option>
                          {groups.map(g => (
                            <option key={g.tempId} value={g.tempId}>{g.name}</option>
                          ))}
                        </select>
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </div>

            {/* 運搬回 */}
            <div className="space-y-4 mb-6">
              <div className="flex items-center justify-between">
                <h2 className="text-sm font-semibold text-gray-700">運搬回</h2>
                <div className="flex gap-2">
                  {hasUnassignedBags && (
                    <button
                      onClick={assignAllRemaining}
                      className="flex items-center gap-1 px-3 py-1.5 bg-amber-500 text-white text-sm rounded-md hover:bg-amber-600"
                    >
                      <Truck className="h-4 w-4" />
                      残り全部 → 新しい回
                    </button>
                  )}
                  <button
                    onClick={addTrip}
                    className="flex items-center gap-1 px-3 py-1.5 bg-green-600 text-white text-sm rounded-md hover:bg-green-700"
                  >
                    <Plus className="h-4 w-4" />
                    回を追加
                  </button>
                </div>
              </div>

              {/* 未割り当てサマリー */}
              {hasUnassignedBags && (
                <div className="bg-amber-50 border border-amber-200 rounded-lg p-3">
                  <p className="text-xs font-medium text-amber-700 mb-2">未割り当て（どの回にも入っていない）</p>
                  <div className="space-y-1">
                    {groups.map(group => {
                      const groupItems: { fId: number; fert: typeof selectedFertilizers[0]; remaining: number }[] = [];
                      for (const fId of group.fieldIds) {
                        for (const fert of selectedFertilizers) {
                          const r = getUnassignedBags(fId, fert.id);
                          if (r > 0) groupItems.push({ fId, fert, remaining: r });
                        }
                      }
                      if (groupItems.length === 0) return null;

                      // グループの肥料ごと合計
                      const fertTotals = selectedFertilizers.map(f => ({
                        name: f.name,
                        total: groupItems.filter(i => i.fert.id === f.id).reduce((s, i) => s + i.remaining, 0),
                      })).filter(f => f.total > 0);

                      return (
                        <div key={group.tempId} className="text-xs text-amber-800">
                          <span className="font-medium">{group.name}</span>:
                          {fertTotals.map((f, i) => (
                            <span key={f.name}>{i > 0 ? ', ' : ' '}{f.name} {f.total.toFixed(1)}</span>
                          ))}
                        </div>
                      );
                    })}
                  </div>
                </div>
              )}

              {trips.map((trip, tripIdx) => {
                const tripGrouped = getTripGroupedFields(trip);
                const tripTotal = getTripTotal(trip);

                return (
                  <div key={trip.tempId} className="bg-white rounded-lg border border-gray-200 overflow-hidden">
                    {/* Trip ヘッダー */}
                    <div className="flex items-center gap-3 bg-blue-50 px-4 py-3 border-b border-blue-100">
                      <span className="font-bold text-blue-800 text-sm">{tripIdx + 1}回目</span>
                      <input
                        type="text"
                        value={trip.name}
                        onChange={e => updateTripName(trip.tempId, e.target.value)}
                        placeholder="名前（任意）"
                        className="border border-gray-300 rounded px-2 py-1 text-sm flex-1 focus:outline-none focus:ring-1 focus:ring-blue-500"
                      />
                      <input
                        type="date"
                        value={trip.date}
                        onChange={e => updateTripDate(trip.tempId, e.target.value)}
                        className="border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500"
                      />
                      <span className="text-sm font-medium text-blue-700">
                        積載: {tripTotal.toFixed(1)}袋
                      </span>
                      {selectedFertilizers.length > 0 && (
                        <span className="text-xs text-blue-500">
                          ({selectedFertilizers.map((f, i) => {
                            const t = getTripFertTotal(trip, f.id);
                            if (t === 0) return null;
                            return <span key={f.id}>{i > 0 ? ' ' : ''}{f.name}:{t.toFixed(1)}</span>;
                          })})
                        </span>
                      )}
                      <button
                        onClick={() => removeTrip(trip.tempId)}
                        className="p-1 text-gray-400 hover:text-red-600"
                        title="この回を削除"
                      >
                        <X className="h-4 w-4" />
                      </button>
                    </div>

                    {/* Trip 内容 */}
                    <div className="p-3">
                      {trip.items.length === 0 ? (
                        <p className="text-xs text-gray-400 italic py-2">圃場が割り当てられていません</p>
                      ) : (
                        <div className="space-y-2">
                          {tripGrouped.map(({ groupName, fieldIds }) => {
                            const groupFertTotals = selectedFertilizers.map(f => ({
                              id: f.id,
                              name: f.name,
                              total: getTripGroupFertTotal(trip, fieldIds, f.id),
                            })).filter(f => f.total > 0);

                            return (
                              <div key={groupName}>
                                {/* グループ小計行 */}
                                <div className="flex items-center gap-2 bg-green-50 px-2 py-1 rounded text-sm font-medium text-green-800">
                                  <span>★ {groupName}</span>
                                  <span className="text-xs text-green-600 flex-1 text-right">
                                    {groupFertTotals.map((f, i) => (
                                      <span key={f.id}>{i > 0 ? '  ' : ''}{f.name}: {f.total.toFixed(2)}</span>
                                    ))}
                                  </span>
                                  {fieldIds.length > 1 && (
                                    <select
                                      value=""
                                      onChange={e => {
                                        const val = e.target.value;
                                        if (val === '__unassigned__') {
                                          returnGroupToUnassigned(fieldIds, trip.tempId);
                                        } else if (val) {
                                          moveGroupToTrip(fieldIds, trip.tempId, val);
                                        }
                                      }}
                                      className="border border-gray-300 rounded px-1.5 py-0.5 text-xs font-normal text-gray-600 focus:outline-none focus:ring-1 focus:ring-blue-500 flex-shrink-0"
                                    >
                                      <option value="">移動...</option>
                                      {trips.filter(t => t.tempId !== trip.tempId).map(t => {
                                        const displayIdx = trips.indexOf(t) + 1;
                                        return (
                                          <option key={t.tempId} value={t.tempId}>→ {displayIdx}回目{t.name ? ` (${t.name})` : ''}</option>
                                        );
                                      })}
                                      <option value="__unassigned__">← 戻す</option>
                                    </select>
                                  )}
                                </div>
                                {/* 圃場行 */}
                                {fieldIds.map(fId => {
                                  const fi = getFieldInfo(fId);
                                  const otherTrips = trips.filter(t => t.tempId !== trip.tempId);
                                  return (
                                    <div key={fId} className="flex items-center gap-2 text-sm pl-4 py-0.5">
                                      <span className="text-gray-700 w-32 truncate">{fi.name}</span>
                                      <span className="text-xs text-gray-500 flex-1">
                                        {selectedFertilizers.map((fert, i) => {
                                          const item = trip.items.find(
                                            it => it.fieldId === fId && it.fertilizerId === fert.id
                                          );
                                          if (!item) return null;
                                          return (
                                            <span key={fert.id}>
                                              {i > 0 && ' / '}
                                              {fert.name}: {item.bags.toFixed(2)}
                                            </span>
                                          );
                                        })}
                                      </span>
                                      <select
                                        value=""
                                        onChange={e => {
                                          const val = e.target.value;
                                          if (val === '__unassigned__') {
                                            returnFieldToUnassigned(fId, trip.tempId);
                                          } else if (val) {
                                            moveFieldToTrip(fId, trip.tempId, val);
                                          }
                                        }}
                                        className="border border-gray-300 rounded px-1.5 py-0.5 text-xs focus:outline-none focus:ring-1 focus:ring-blue-500 flex-shrink-0"
                                      >
                                        <option value="">移動...</option>
                                        {otherTrips.map(t => {
                                          const displayIdx = trips.indexOf(t) + 1;
                                          return (
                                            <option key={t.tempId} value={t.tempId}>→ {displayIdx}回目{t.name ? ` (${t.name})` : ''}</option>
                                          );
                                        })}
                                        <option value="__unassigned__">← 戻す</option>
                                      </select>
                                    </div>
                                  );
                                })}
                              </div>
                            );
                          })}
                        </div>
                      )}

                      {/* このtripに追加 */}
                      {hasUnassignedBags && (
                        <div className="mt-2 pt-2 border-t border-gray-100 flex gap-2 flex-wrap">
                          {/* グループ一括追加 */}
                          <select
                            value=""
                            onChange={e => {
                              if (e.target.value) {
                                assignGroupToTrip(e.target.value, trip.tempId);
                              }
                            }}
                            className="border border-gray-300 rounded px-2 py-1 text-xs focus:outline-none focus:ring-1 focus:ring-green-500"
                          >
                            <option value="">+ グループを追加...</option>
                            {groups.map(g => {
                              const hasRemaining = g.fieldIds.some(fId =>
                                selectedFertilizers.some(f => getUnassignedBags(fId, f.id) > 0)
                              );
                              if (!hasRemaining) return null;
                              return (
                                <option key={g.tempId} value={g.tempId}>★ {g.name}（{g.fieldIds.length}圃場）</option>
                              );
                            })}
                          </select>
                          {/* 圃場単体追加 */}
                          <select
                            value=""
                            onChange={e => {
                              if (e.target.value) {
                                assignFieldToTrip(Number(e.target.value), trip.tempId);
                              }
                            }}
                            className="border border-gray-300 rounded px-2 py-1 text-xs focus:outline-none focus:ring-1 focus:ring-green-500"
                          >
                            <option value="">+ 圃場を追加...</option>
                            {groups.map(g => {
                              const fieldsWithRemaining = g.fieldIds.filter(fId =>
                                selectedFertilizers.some(f => getUnassignedBags(fId, f.id) > 0)
                              );
                              if (fieldsWithRemaining.length === 0) return null;
                              return (
                                <optgroup key={g.tempId} label={g.name}>
                                  {fieldsWithRemaining.map(fId => (
                                    <option key={fId} value={fId}>{getFieldInfo(fId).name}</option>
                                  ))}
                                </optgroup>
                              );
                            })}
                            {unassignedFields.filter(fi =>
                              selectedFertilizers.some(f => getUnassignedBags(fi.id, f.id) > 0)
                            ).length > 0 && (
                              <optgroup label="未グループ">
                                {unassignedFields.filter(fi =>
                                  selectedFertilizers.some(f => getUnassignedBags(fi.id, f.id) > 0)
                                ).map(fi => (
                                  <option key={fi.id} value={fi.id}>{fi.name}</option>
                                ))}
                              </optgroup>
                            )}
                          </select>
                        </div>
                      )}
                    </div>
                  </div>
                );
              })}
            </div>
          </>
        )}

        {/* フッターボタン */}
        <div className="flex justify-end gap-3">
          <button
            onClick={() => router.push('/distribution')}
            className="px-4 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-100 text-gray-700"
          >
            キャンセル
          </button>
          <button
            onClick={handleSave}
            disabled={saving}
            className="px-6 py-2 text-sm bg-green-600 text-white rounded-md hover:bg-green-700 disabled:opacity-50 font-medium"
          >
            {saving ? '保存中...' : '保存'}
          </button>
        </div>
      </main>
    </div>
  );
}
