'use client';

import { useState, useEffect, useMemo } from 'react';
import { api } from '@/lib/api';
import { Field, Crop, Plan } from '@/types';
import Navbar from '@/components/Navbar';
import { Menu, X, BarChart3, ChevronRight, ChevronDown, ArrowUp, ArrowDown, Copy, Settings, Trash2, CheckSquare, Search, History } from 'lucide-react';

interface SummaryItem {
  cropId: number;
  cropName: string;
  areaTan: number;
  varieties: {
    varietyId: number | null;
    varietyName: string;
    areaTan: number;
  }[];
}

type SortType = 'custom' | 'group' | 'crop';

export default function AllocationPage() {
  const [fields, setFields] = useState<Field[]>([]);
  const [crops, setCrops] = useState<Crop[]>([]);
  const [plans, setPlans] = useState<Plan[]>([]);
  const [year, setYear] = useState<number>(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('allocationYear');
      if (saved) return parseInt(saved);
    }
    return new Date().getFullYear();
  });
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState<number | null>(null);
  const [showSidebar, setShowSidebar] = useState(true);
  const [showMobileSummary, setShowMobileSummary] = useState(false);
  const [expandedCrops, setExpandedCrops] = useState<Set<number>>(new Set());
  const [sortType, setSortType] = useState<SortType>('custom');
  const [copying, setCopying] = useState(false);
  const [addingVariety, setAddingVariety] = useState<{ fieldId: number; cropId: number } | null>(null);
  const [newVarietyName, setNewVarietyName] = useState('');
  const [showVarietyManager, setShowVarietyManager] = useState(false);
  const [managerCropId, setManagerCropId] = useState<number | null>(null);
  const [selectedFields, setSelectedFields] = useState<Set<number>>(new Set());
  const [bulkCropId, setBulkCropId] = useState<number | 0>(0);
  const [bulkVarietyId, setBulkVarietyId] = useState<number | 0>(0);
  const [bulkUpdating, setBulkUpdating] = useState(false);
  const [searchText, setSearchText] = useState('');
  const [filterCropId, setFilterCropId] = useState<number | 0>(0);
  const [filterUnassigned, setFilterUnassigned] = useState(false);
  const [toast, setToast] = useState<{ type: 'success' | 'error'; message: string } | null>(null);

  useEffect(() => {
    if (!toast) return;
    const timer = window.setTimeout(() => setToast(null), 4000);
    return () => window.clearTimeout(timer);
  }, [toast]);

  useEffect(() => {
    localStorage.setItem('allocationYear', String(year));
    fetchData();
  }, [year]);

  const currentYear = new Date().getFullYear();
  const isPastYear = year < currentYear;

  const fetchData = async (background = false) => {
    if (!background) setLoading(true);
    try {
      const [fieldsRes, cropsRes, plansRes] = await Promise.all([
        api.get('/fields/?ordering=group_name,display_order,id'),
        api.get('/plans/crops/'),
        api.get(`/plans/?year=${year}`),
      ]);
      setFields(fieldsRes.data);
      setCrops(cropsRes.data);
      setPlans(plansRes.data);
    } catch (error) {
      console.error('Failed to fetch data:', error);
    } finally {
      if (!background) setLoading(false);
    }
  };

  const summary = useMemo(() => {
    const cropSummary = new Map<number, SummaryItem>();
    let totalAreaTan = 0;
    let unassignedAreaTan = 0;

    fields.forEach((field) => {
      const area = parseFloat(field.area_tan) || 0;
      totalAreaTan += area;
      
      const plan = plans.find((p) => p.field === field.id);
      
      if (!plan?.crop) {
        unassignedAreaTan += area;
        return;
      }

      if (!cropSummary.has(plan.crop)) {
        const crop = crops.find((c) => c.id === plan.crop);
        cropSummary.set(plan.crop, {
          cropId: plan.crop,
          cropName: crop?.name || '不明',
          areaTan: 0,
          varieties: [],
        });
      }

      const item = cropSummary.get(plan.crop)!;
      item.areaTan += area;

      const varietyId = plan.variety;
      const varietyName = plan.variety_name || '（品種未選択）';
      
      let varietyItem = item.varieties.find((v) => v.varietyId === varietyId);
      if (!varietyItem) {
        varietyItem = { varietyId, varietyName, areaTan: 0 };
        item.varieties.push(varietyItem);
      }
      varietyItem.areaTan += area;
    });

    return {
      totalAreaTan,
      unassignedAreaTan,
      items: Array.from(cropSummary.values()),
    };
  }, [fields, plans, crops]);

  const sortedFields = useMemo(() => {
    const sorted = [...fields];
    
    if (sortType === 'custom') {
      sorted.sort((a, b) => {
        const orderA = a.display_order ?? 0;
        const orderB = b.display_order ?? 0;
        return orderA - orderB;
      });
    } else if (sortType === 'group') {
      sorted.sort((a, b) => {
        const groupA = a.group_name || '';
        const groupB = b.group_name || '';
        if (groupA !== groupB) return groupA.localeCompare(groupB);
        const orderA = a.display_order ?? 0;
        const orderB = b.display_order ?? 0;
        return orderA - orderB;
      });
    } else if (sortType === 'crop') {
      sorted.sort((a, b) => {
        const planA = plans.find((p) => p.field === a.id);
        const planB = plans.find((p) => p.field === b.id);
        const cropA = planA?.crop || 0;
        const cropB = planB?.crop || 0;
        if (cropA !== cropB) return cropA - cropB;
        const orderA = a.display_order ?? 0;
        const orderB = b.display_order ?? 0;
        return orderA - orderB;
      });
    }
    
    return sorted;
  }, [fields, sortType, plans]);

  const filteredFields = useMemo(() => {
    let result = sortedFields;

    if (searchText) {
      const query = searchText.toLowerCase();
      result = result.filter(
        (f) =>
          f.name.toLowerCase().includes(query) ||
          (f.address && f.address.toLowerCase().includes(query))
      );
    }

    if (filterCropId) {
      result = result.filter((f) => {
        const plan = plans.find((p) => p.field === f.id);
        return plan?.crop === filterCropId;
      });
    }

    if (filterUnassigned) {
      result = result.filter((f) => {
        const plan = plans.find((p) => p.field === f.id);
        return !plan?.crop;
      });
    }

    return result;
  }, [sortedFields, searchText, filterCropId, filterUnassigned, plans]);

  const groupOptions = useMemo(() => {
    const groups = new Set<string>();
    fields.forEach(f => {
      if (f.group_name) groups.add(f.group_name);
    });
    return Array.from(groups).sort();
  }, [fields]);

  const getPlanForField = (fieldId: number): Plan | undefined => {
    return plans.find((p) => p.field === fieldId);
  };

  const handleCropChange = async (fieldId: number, cropId: string) => {
    const crop = parseInt(cropId);
    if (!crop) return;

    const existingPlan = getPlanForField(fieldId);
    setSaving(fieldId);

    try {
      if (existingPlan) {
        await api.patch(`/plans/${existingPlan.id}/`, {
          crop,
          variety: null,
          notes: existingPlan.notes,
        });
      } else {
        await api.post('/plans/', {
          field: fieldId,
          year,
          crop,
          variety: null,
          notes: '',
        });
      }
      await fetchData(true);
    } catch (error) {
      console.error('Failed to save crop:', error);
    } finally {
      setSaving(null);
    }
  };

  const handleVarietyChange = async (fieldId: number, varietyId: string) => {
    const variety = parseInt(varietyId) || null;
    const existingPlan = getPlanForField(fieldId);

    if (!existingPlan || !existingPlan.crop) return;
    if ((existingPlan.variety || null) === variety) return;

    const nextVarietyName =
      variety === null
        ? '（品種未選択）'
        : getVarietiesForCrop(existingPlan.crop).find((item) => item.id === variety)?.name || '不明';
    const currentVarietyName = existingPlan.variety_name || '（品種未選択）';

    const shouldProceed = confirm(
      [
        `品種を「${currentVarietyName}」から「${nextVarietyName}」へ変更します。`,
        '施肥計画・田植え計画の関連エントリが自動で移動する場合があります。',
        '実行しますか？',
      ].join('\n')
    );
    if (!shouldProceed) return;

    setSaving(fieldId);

    try {
      const res = await api.patch(`/plans/${existingPlan.id}/`, {
        variety,
        notes: existingPlan.notes,
      });
      const updatedPlan: Plan = res.data;
      const movedCount = updatedPlan.latest_variety_change?.fertilizer_moved_entry_count ?? 0;
      setToast({
        type: 'success',
        message:
          movedCount > 0
            ? `品種を変更し、施肥計画 ${movedCount} 件を移動しました。`
            : '品種を変更しました。関連する施肥計画の移動はありませんでした。',
      });
      await fetchData(true);
    } catch (error) {
      console.error('Failed to save variety:', error);
      setToast({
        type: 'error',
        message: '品種変更に失敗しました。',
      });
    } finally {
      setSaving(null);
    }
  };

  const handleNotesChange = async (fieldId: number, notes: string) => {
    const existingPlan = getPlanForField(fieldId);
    if (!existingPlan) return;

    setSaving(fieldId);

    try {
      await api.patch(`/plans/${existingPlan.id}/`, { notes });
      await fetchData(true);
    } catch (error) {
      console.error('Failed to save notes:', error);
    } finally {
      setSaving(null);
    }
  };

  const handleGroupChange = async (fieldId: number, groupName: string) => {
    setFields(prev => prev.map(f => 
      f.id === fieldId ? { ...f, group_name: groupName || null } : f
    ));
    
    try {
      await api.patch(`/fields/${fieldId}/`, { 
        group_name: groupName || null 
      });
    } catch (error) {
      console.error('Failed to save group:', error);
      await fetchData(true);
    }
  };

  const moveUp = async (index: number) => {
    if (index === 0) return;
    const current = sortedFields[index];
    const prev = sortedFields[index - 1];
    
    setSaving(current.id);
    setSaving(prev.id);

    try {
      const newOrderCurrent = prev.display_order ?? (index - 1);
      const newOrderPrev = current.display_order ?? index;
      
      await Promise.all([
        api.patch(`/fields/${current.id}/`, { display_order: newOrderCurrent }),
        api.patch(`/fields/${prev.id}/`, { display_order: newOrderPrev })
      ]);
      
      await fetchData(true);
    } catch (error) {
      console.error('Failed to move up:', error);
    } finally {
      setSaving(null);
    }
  };

  const moveDown = async (index: number) => {
    if (index === sortedFields.length - 1) return;
    const current = sortedFields[index];
    const next = sortedFields[index + 1];
    
    setSaving(current.id);
    setSaving(next.id);

    try {
      const newOrderCurrent = next.display_order ?? (index + 1);
      const newOrderPrev = current.display_order ?? index;
      
      await Promise.all([
        api.patch(`/fields/${current.id}/`, { display_order: newOrderCurrent }),
        api.patch(`/fields/${next.id}/`, { display_order: newOrderPrev })
      ]);
      
      await fetchData(true);
    } catch (error) {
      console.error('Failed to move down:', error);
    } finally {
      setSaving(null);
    }
  };

  const handleAddVariety = async (fieldId: number, cropId: number) => {
    const name = newVarietyName.trim();
    if (!name) return;

    try {
      const res = await api.post('/plans/varieties/', { crop: cropId, name });
      setNewVarietyName('');
      setAddingVariety(null);
      await fetchData(true);
      // Auto-select the new variety
      const plan = getPlanForField(fieldId);
      if (plan) {
        await api.patch(`/plans/${plan.id}/`, { variety: res.data.id });
        await fetchData(true);
      }
    } catch (error: any) {
      if (error.response?.status === 400) {
        alert('この品種名は既に登録されています');
      } else {
        console.error('Failed to add variety:', error);
        alert('品種の追加に失敗しました');
      }
    }
  };

  const handleDeleteVariety = async (varietyId: number, varietyName: string) => {
    if (!confirm(`品種「${varietyName}」を削除しますか？\nこの品種が設定されている作付け計画がある場合、削除できません。`)) return;

    try {
      await api.delete(`/plans/varieties/${varietyId}/`);
      await fetchData(true);
    } catch (error: any) {
      console.error('Failed to delete variety:', error);
      alert('品種の削除に失敗しました。使用中の品種は削除できません。');
    }
  };

  const handleUpdateVarietyDefaultBoxes = async (varietyId: number, defaultBoxes: string) => {
    try {
      const variety = crops.flatMap((crop) => crop.varieties).find((item) => item.id === varietyId);
      if (!variety) return;
      await api.patch(`/plans/varieties/${varietyId}/`, {
        default_seedling_boxes_per_tan: defaultBoxes,
      });
      await fetchData(true);
    } catch (error) {
      console.error('Failed to update variety default boxes:', error);
      alert('品種デフォルトの更新に失敗しました');
    }
  };

  const toggleFieldSelection = (fieldId: number) => {
    setSelectedFields((prev) => {
      const next = new Set(prev);
      if (next.has(fieldId)) next.delete(fieldId);
      else next.add(fieldId);
      return next;
    });
  };

  const toggleAllFields = () => {
    if (selectedFields.size === filteredFields.length) {
      setSelectedFields(new Set());
    } else {
      setSelectedFields(new Set(filteredFields.map((f) => f.id)));
    }
  };

  const handleBulkUpdate = async () => {
    if (selectedFields.size === 0 || !bulkCropId) return;
    if (!confirm(`選択した${selectedFields.size}件の圃場に一括で作物・品種を設定します。\n既存の設定は上書きされます。実行しますか？`)) return;

    setBulkUpdating(true);
    try {
      await api.post('/plans/bulk_update/', {
        field_ids: Array.from(selectedFields),
        year,
        crop: bulkCropId,
        variety: bulkVarietyId || null,
      });
      setSelectedFields(new Set());
      setBulkCropId(0);
      setBulkVarietyId(0);
      await fetchData();
    } catch (error) {
      console.error('Bulk update failed:', error);
      alert('一括更新に失敗しました');
    } finally {
      setBulkUpdating(false);
    }
  };

  const handleCopyFromPreviousYear = async () => {
    const fromYear = year - 1;
    if (!confirm(`${fromYear}年度の作付け計画を${year}年度にコピーします。\n既に設定済みの圃場はスキップされます。\n実行しますか？`)) return;

    setCopying(true);
    try {
      const res = await api.post('/plans/copy_from_previous_year/', {
        from_year: fromYear,
        to_year: year,
      });
      alert(res.data.message || 'コピーが完了しました');
      await fetchData();
    } catch (error: any) {
      console.error('Failed to copy:', error);
      alert(error.response?.data?.error || 'コピーに失敗しました');
    } finally {
      setCopying(false);
    }
  };

  const getVarietiesForCrop = (cropId: number) => {
    const crop = crops.find((c) => c.id === cropId);
    return crop?.varieties || [];
  };

  const toggleCropExpand = (cropId: number) => {
    setExpandedCrops((prev) => {
      const next = new Set(prev);
      if (next.has(cropId)) {
        next.delete(cropId);
      } else {
        next.add(cropId);
      }
      return next;
    });
  };

  const renderSidebar = () => (
    <>
      <div className="p-4 border-b flex justify-between items-center">
        {showSidebar && <h2 className="font-bold text-gray-900">集計</h2>}
        <button
          onClick={() => setShowSidebar(!showSidebar)}
          className="p-1 hover:bg-gray-100 rounded"
        >
          {showSidebar ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
        </button>
      </div>

      {showSidebar && (
        <div className="p-4">
          <div className="mb-4">
            <div className="text-sm text-gray-500">合計面積</div>
            <div className="text-2xl font-bold text-gray-900">
              {summary.totalAreaTan.toFixed(2)} 反
            </div>
            <div className="text-xs text-gray-500">
              ({Math.round(summary.totalAreaTan * 1000)} m²)
            </div>
          </div>

          {summary.unassignedAreaTan > 0 && (
            <div className="mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-md">
              <div className="text-sm text-yellow-800">未設定</div>
              <div className="font-bold text-yellow-900">
                {summary.unassignedAreaTan.toFixed(2)} 反
              </div>
            </div>
          )}

          <div className="space-y-2">
            {summary.items.map((item) => (
              <div key={item.cropId} className="border rounded-md overflow-hidden">
                <button
                  onClick={() => toggleCropExpand(item.cropId)}
                  className="w-full p-3 flex items-center justify-between bg-gray-50 hover:bg-gray-100"
                >
                  <div className="text-left">
                    <div className="font-medium text-gray-900">{item.cropName}</div>
                    <div className="text-sm text-gray-500">
                      {item.areaTan.toFixed(2)} 反
                    </div>
                  </div>
                  {expandedCrops.has(item.cropId) ? (
                    <ChevronDown className="h-4 w-4 text-gray-500" />
                  ) : (
                    <ChevronRight className="h-4 w-4 text-gray-500" />
                  )}
                </button>

                {expandedCrops.has(item.cropId) && (
                  <div className="border-t bg-white">
                    {item.varieties.map((v, idx) => (
                      <div
                        key={idx}
                        className="px-3 py-2 flex justify-between text-sm"
                      >
                        <span className="text-gray-600">{v.varietyName}</span>
                        <span className="text-gray-900 font-medium">
                          {v.areaTan.toFixed(2)} 反
                        </span>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>
      )}
    </>
  );

  if (loading) {
    return (
      <div className="min-h-screen bg-gray-50">
        <Navbar />
        <div className="flex items-center justify-center h-64">
          <div className="text-gray-500">読み込み中...</div>
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-gray-50">
      <Navbar />

      <div className="flex flex-col lg:flex-row">
        {/* PC用サイドバー */}
        <div
          className={`hidden lg:block transition-all duration-300 ${
            showSidebar ? 'w-64' : 'w-12'
          } bg-white shadow rounded-lg m-4 overflow-hidden flex-shrink-0`}
        >
          {renderSidebar()}
        </div>

        {/* メインコンテンツ */}
        <div className="flex-1 min-w-0 p-4 lg:p-0">
          <div className="max-w-7xl mx-auto">
            {toast && (
              <div
                className={`mb-4 rounded-md border px-4 py-3 text-sm ${
                  toast.type === 'success'
                    ? 'border-green-300 bg-green-50 text-green-800'
                    : 'border-red-300 bg-red-50 text-red-800'
                }`}
              >
                {toast.message}
              </div>
            )}
            <div className="mb-6 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
              <h1 className="text-2xl font-bold text-gray-900">
                作付け計画 <span className="text-green-700">{year}年度</span>
              </h1>

              {/* スマホ用集計ボタン */}
              <button
                className="lg:hidden px-4 py-2 bg-blue-600 text-white rounded-md flex items-center gap-2"
                onClick={() => setShowMobileSummary(true)}
              >
                <BarChart3 className="h-4 w-4" />
                集計を表示
              </button>

              <div className="flex items-center gap-2">
                <select
                  value={sortType}
                  onChange={(e) => setSortType(e.target.value as SortType)}
                  className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 text-sm"
                >
                  <option value="custom">カスタム順</option>
                  <option value="group">グループ順</option>
                  <option value="crop">作付け順</option>
                </select>

                <label htmlFor="year" className="text-sm font-medium text-gray-700">
                  作付年度:
                </label>
                <select
                  id="year"
                  value={year}
                  onChange={(e) => setYear(parseInt(e.target.value))}
                  className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 font-semibold"
                >
                  {Array.from({ length: 5 }, (_, i) => new Date().getFullYear() - 2 + i).map((y) => (
                    <option key={y} value={y}>{y}年</option>
                  ))}
                </select>

                <button
                  onClick={handleCopyFromPreviousYear}
                  disabled={copying}
                  className="flex items-center px-3 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 text-gray-700"
                  title={`${year - 1}年度の計画をコピー`}
                >
                  <Copy className="h-4 w-4 mr-1" />
                  {copying ? 'コピー中...' : '前年度コピー'}
                </button>

                <button
                  onClick={() => { setShowVarietyManager(true); setManagerCropId(crops[0]?.id || null); }}
                  className="flex items-center px-3 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 text-gray-700"
                  title="品種管理"
                >
                  <Settings className="h-4 w-4 mr-1" />
                  品種管理
                </button>
              </div>
            </div>

            {/* 検索・フィルタバー */}
            <div className="mb-4 flex flex-wrap items-center gap-2">
              <div className="relative flex-1 min-w-[200px] max-w-sm">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" />
                <input
                  type="text"
                  value={searchText}
                  onChange={(e) => setSearchText(e.target.value)}
                  placeholder="圃場名・住所で検索..."
                  className="w-full pl-9 pr-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500"
                />
              </div>
              <select
                value={filterCropId || ''}
                onChange={(e) => { setFilterCropId(parseInt(e.target.value) || 0); setFilterUnassigned(false); }}
                className="px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500"
              >
                <option value="">全作物</option>
                {crops.map((crop) => (
                  <option key={crop.id} value={crop.id}>{crop.name}</option>
                ))}
              </select>
              <label className="flex items-center gap-1.5 text-sm text-gray-700 cursor-pointer">
                <input
                  type="checkbox"
                  checked={filterUnassigned}
                  onChange={(e) => { setFilterUnassigned(e.target.checked); if (e.target.checked) setFilterCropId(0); }}
                  className="rounded border-gray-300 text-green-600 focus:ring-green-500"
                />
                未割当のみ
              </label>
              {(searchText || filterCropId || filterUnassigned) && (
                <span className="text-sm text-gray-500">
                  {filteredFields.length}/{fields.length}件
                </span>
              )}
            </div>

            {filteredFields.length === 0 && fields.length > 0 ? (
              <div className="bg-white rounded-lg shadow p-8 text-center">
                <p className="text-gray-500">
                  条件に一致する圃場がありません。
                </p>
              </div>
            ) : sortedFields.length === 0 ? (
              <div className="bg-white rounded-lg shadow p-8 text-center">
                <p className="text-gray-500">
                  圃場データがありません。インポートを実行してください。
                </p>
              </div>
            ) : (
              <>
                {isPastYear && (
                  <div className="mb-4 p-3 bg-amber-50 border border-amber-300 rounded-md flex items-center justify-between">
                    <p className="text-sm text-amber-800 font-medium">
                      {year}年度のデータを参照中（過去年度）
                    </p>
                    <button
                      onClick={() => setYear(currentYear)}
                      className="text-sm text-amber-700 underline hover:text-amber-900"
                    >
                      {currentYear}年度に戻る
                    </button>
                  </div>
                )}

                <div className="mb-4 p-3 bg-blue-50 border border-blue-200 rounded-md">
                  <p className="text-sm text-blue-800">
                    💡 グループ名を入力して「グループ順」で並び替え、「↑」「↓」ボタンで順序を変更できます
                  </p>
                </div>

                {selectedFields.size > 0 && (
                  <div className="mb-4 p-3 bg-green-50 border border-green-200 rounded-md flex items-center gap-3 flex-wrap">
                    <span className="text-sm font-medium text-green-800">
                      <CheckSquare className="h-4 w-4 inline mr-1" />
                      {selectedFields.size}件選択中
                    </span>
                    <select
                      value={bulkCropId || ''}
                      onChange={(e) => { setBulkCropId(parseInt(e.target.value) || 0); setBulkVarietyId(0); }}
                      className="px-2 py-1.5 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500"
                    >
                      <option value="">作物を選択</option>
                      {crops.map((crop) => (
                        <option key={crop.id} value={crop.id}>{crop.name}</option>
                      ))}
                    </select>
                    {bulkCropId > 0 && (
                      <select
                        value={bulkVarietyId || ''}
                        onChange={(e) => setBulkVarietyId(parseInt(e.target.value) || 0)}
                        className="px-2 py-1.5 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500"
                      >
                        <option value="">品種を選択</option>
                        {getVarietiesForCrop(bulkCropId).map((v) => (
                          <option key={v.id} value={v.id}>{v.name}</option>
                        ))}
                      </select>
                    )}
                    <button
                      onClick={handleBulkUpdate}
                      disabled={!bulkCropId || bulkUpdating}
                      className="px-3 py-1.5 bg-green-600 text-white rounded-md text-sm hover:bg-green-700 disabled:opacity-50"
                    >
                      {bulkUpdating ? '更新中...' : '一括設定'}
                    </button>
                    <button
                      onClick={() => setSelectedFields(new Set())}
                      className="px-3 py-1.5 text-gray-600 hover:text-gray-800 text-sm"
                    >
                      選択解除
                    </button>
                  </div>
                )}

                <div className={`rounded-lg shadow overflow-hidden ${isPastYear ? 'bg-amber-50/50 ring-1 ring-amber-200' : 'bg-white'}`}>
                  <div className="overflow-x-auto">
                    <table className="min-w-full divide-y divide-gray-200">
                      <thead className="bg-gray-50">
                        <tr>
                          <th className="px-2 py-3 w-10">
                            <input
                              type="checkbox"
                              checked={selectedFields.size === filteredFields.length && filteredFields.length > 0}
                              onChange={toggleAllFields}
                              className="rounded border-gray-300 text-green-600 focus:ring-green-500"
                            />
                          </th>
                          {sortType === 'custom' && (
                            <th className="px-2 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-20">
                              順序
                            </th>
                          )}
                          <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                            グループ
                          </th>
                          <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                            圃場名
                          </th>
                          <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                            面積(反)
                          </th>
                          <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                            作物
                          </th>
                          <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                            品種
                          </th>
                          <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                            備考
                          </th>
                        </tr>
                      </thead>
                      <tbody className="bg-white divide-y divide-gray-200">
                        {filteredFields.map((field, index) => {
                          const plan = getPlanForField(field.id);
                          const selectedCropId = plan?.crop || 0;
                          const selectedVarietyId = plan?.variety || 0;

                          return (
                            <tr key={field.id} className={`hover:bg-gray-50 ${selectedFields.has(field.id) ? 'bg-green-50' : ''}`}>
                              <td className="px-2 py-4 w-10">
                                <input
                                  type="checkbox"
                                  checked={selectedFields.has(field.id)}
                                  onChange={() => toggleFieldSelection(field.id)}
                                  className="rounded border-gray-300 text-green-600 focus:ring-green-500"
                                />
                              </td>
                              {sortType === 'custom' && (
                                <td className="px-2 py-4 whitespace-nowrap">
                                  <div className="flex items-center gap-1">
                                    <button
                                      onClick={() => moveUp(index)}
                                      disabled={index === 0 || saving === field.id}
                                      className="p-1 hover:bg-gray-100 rounded disabled:opacity-30"
                                      title="上へ移動"
                                    >
                                      <ArrowUp className="h-4 w-4" />
                                    </button>
                                    <button
                                      onClick={() => moveDown(index)}
                                      disabled={index === filteredFields.length - 1 || saving === field.id}
                                      className="p-1 hover:bg-gray-100 rounded disabled:opacity-30"
                                      title="下へ移動"
                                    >
                                      <ArrowDown className="h-4 w-4" />
                                    </button>
                                  </div>
                                </td>
                              )}
                              <td className="px-4 py-4 whitespace-nowrap">
                                <input
                                  list="group-options"
                                  value={field.group_name || ''}
                                  onChange={(e) => handleGroupChange(field.id, e.target.value)}
                                  disabled={saving === field.id}
                                  placeholder="選択または入力"
                                  className="w-36 px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 disabled:opacity-50"
                                />
                                <datalist id="group-options">
                                  {groupOptions.map((g) => (
                                    <option key={g} value={g} />
                                  ))}
                                </datalist>
                              </td>
                              <td className="px-6 py-4 whitespace-nowrap">
                                <div className="text-sm font-medium text-gray-900">
                                  {field.name}
                                </div>
                                <div className="text-xs text-gray-500">
                                  {field.address}
                                </div>
                              </td>
                              <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                                {field.area_tan}
                              </td>
                              <td className="px-6 py-4 whitespace-nowrap">
                                <select
                                  value={selectedCropId || ''}
                                  onChange={(e) =>
                                    handleCropChange(field.id, e.target.value)
                                  }
                                  disabled={saving === field.id}
                                  className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 text-sm disabled:opacity-50"
                                >
                                  <option value="">選択してください</option>
                                  {crops.map((crop) => (
                                    <option key={crop.id} value={crop.id}>
                                      {crop.name}
                                    </option>
                                  ))}
                                </select>
                              </td>
                              <td className="px-6 py-4 whitespace-nowrap">
                                {addingVariety?.fieldId === field.id ? (
                                  <div className="flex items-center gap-1">
                                    <input
                                      type="text"
                                      value={newVarietyName}
                                      onChange={(e) => setNewVarietyName(e.target.value)}
                                      onKeyDown={(e) => {
                                        if (e.key === 'Enter') handleAddVariety(field.id, addingVariety.cropId);
                                        if (e.key === 'Escape') { setAddingVariety(null); setNewVarietyName(''); }
                                      }}
                                      placeholder="品種名を入力"
                                      className="px-2 py-1.5 border border-green-400 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 w-32"
                                      autoFocus
                                    />
                                    <button
                                      onClick={() => handleAddVariety(field.id, addingVariety.cropId)}
                                      className="px-2 py-1.5 bg-green-600 text-white rounded text-xs hover:bg-green-700"
                                    >
                                      追加
                                    </button>
                                    <button
                                      onClick={() => { setAddingVariety(null); setNewVarietyName(''); }}
                                      className="px-2 py-1.5 text-gray-500 hover:text-gray-700 text-xs"
                                    >
                                      取消
                                    </button>
                                  </div>
                                ) : (
                                  <div className="flex items-center gap-2">
                                    <select
                                      value={selectedVarietyId || ''}
                                      onChange={(e) => {
                                        if (e.target.value === '__add__') {
                                          setAddingVariety({ fieldId: field.id, cropId: selectedCropId });
                                          setNewVarietyName('');
                                        } else {
                                          handleVarietyChange(field.id, e.target.value);
                                        }
                                      }}
                                      disabled={saving === field.id || !selectedCropId}
                                      className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 text-sm disabled:opacity-50 disabled:bg-gray-100"
                                    >
                                      <option value="">選択してください</option>
                                      {getVarietiesForCrop(selectedCropId).map((variety) => (
                                        <option key={variety.id} value={variety.id}>
                                          {variety.name}
                                        </option>
                                      ))}
                                      {selectedCropId > 0 && <option value="__add__">+ 新しい品種を追加...</option>}
                                    </select>
                                    {plan?.latest_variety_change && (
                                      <div
                                        className="inline-flex items-center gap-1 rounded-full border border-amber-300 bg-amber-50 px-2 py-1 text-xs text-amber-800"
                                        title={[
                                          `変更日時: ${new Date(plan.latest_variety_change.changed_at).toLocaleString('ja-JP')}`,
                                          `変更前: ${plan.latest_variety_change.old_variety_name || '未設定'}`,
                                          `変更後: ${plan.latest_variety_change.new_variety_name || '未設定'}`,
                                          `施肥移動件数: ${plan.latest_variety_change.fertilizer_moved_entry_count}`,
                                        ].join('\n')}
                                      >
                                        <History className="h-3 w-3" />
                                        変更履歴あり
                                      </div>
                                    )}
                                  </div>
                                )}
                              </td>
                              <td className="px-6 py-4">
                                <input
                                  type="text"
                                  value={plan?.notes || ''}
                                  onChange={(e) =>
                                    handleNotesChange(field.id, e.target.value)
                                  }
                                  disabled={saving === field.id || !plan}
                                  placeholder="備考を入力"
                                  className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 text-sm w-full disabled:opacity-50 disabled:bg-gray-100"
                                />
                              </td>
                            </tr>
                          );
                        })}
                      </tbody>
                    </table>
                  </div>
                </div>
              </>
            )}
          </div>
        </div>
      </div>

      {/* スマホ用モーダル */}
      {showMobileSummary && (
        <div className="fixed inset-0 z-50 lg:hidden">
          <div
            className="absolute inset-0 bg-black/50"
            onClick={() => setShowMobileSummary(false)}
          />
          <div className="absolute inset-y-0 right-0 w-full max-w-md bg-white shadow-xl">
            <div className="flex flex-col h-full">
              <div className="flex items-center justify-between p-4 border-b">
                <h2 className="font-bold text-lg">集計</h2>
                <button
                  onClick={() => setShowMobileSummary(false)}
                  className="p-2 hover:bg-gray-100 rounded"
                >
                  <X className="h-5 w-5" />
                </button>
              </div>
              <div className="flex-1 overflow-y-auto p-4">
                <div className="mb-4">
                  <div className="text-sm text-gray-500">合計面積</div>
                  <div className="text-2xl font-bold text-gray-900">
                    {summary.totalAreaTan.toFixed(2)} 反
                  </div>
                  <div className="text-xs text-gray-500">
                    ({Math.round(summary.totalAreaTan * 1000)} m²)
                  </div>
                </div>

                {summary.unassignedAreaTan > 0 && (
                  <div className="mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-md">
                    <div className="text-sm text-yellow-800">未設定</div>
                    <div className="font-bold text-yellow-900">
                      {summary.unassignedAreaTan.toFixed(2)} 反
                    </div>
                  </div>
                )}

                <div className="space-y-2">
                  {summary.items.map((item) => (
                    <div key={item.cropId} className="border rounded-md overflow-hidden">
                      <button
                        onClick={() => toggleCropExpand(item.cropId)}
                        className="w-full p-3 flex items-center justify-between bg-gray-50 hover:bg-gray-100"
                      >
                        <div className="text-left">
                          <div className="font-medium text-gray-900">
                            {item.cropName}
                          </div>
                          <div className="text-sm text-gray-500">
                            {item.areaTan.toFixed(2)} 反
                          </div>
                        </div>
                        {expandedCrops.has(item.cropId) ? (
                          <ChevronDown className="h-4 w-4 text-gray-500" />
                        ) : (
                          <ChevronRight className="h-4 w-4 text-gray-500" />
                        )}
                      </button>

                      {expandedCrops.has(item.cropId) && (
                        <div className="border-t bg-white">
                          {item.varieties.map((v, idx) => (
                            <div
                              key={idx}
                              className="px-3 py-2 flex justify-between text-sm"
                            >
                              <span className="text-gray-600">{v.varietyName}</span>
                              <span className="text-gray-900 font-medium">
                                {v.areaTan.toFixed(2)} 反
                              </span>
                            </div>
                          ))}
                        </div>
                      )}
                    </div>
                  ))}
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
      {/* 品種管理モーダル */}
      {showVarietyManager && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
          <div className="bg-white rounded-lg shadow-xl w-full max-w-md max-h-[80vh] flex flex-col">
            <div className="flex items-center justify-between p-4 border-b">
              <h3 className="text-lg font-bold text-gray-900">品種管理</h3>
              <button onClick={() => setShowVarietyManager(false)} className="text-gray-400 hover:text-gray-600">
                <X className="h-5 w-5" />
              </button>
            </div>

            <div className="p-4 border-b">
              <label className="text-sm text-gray-600 mr-2">作物:</label>
              <select
                value={managerCropId || ''}
                onChange={(e) => setManagerCropId(parseInt(e.target.value) || null)}
                className="px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500"
              >
                {crops.map((crop) => (
                  <option key={crop.id} value={crop.id}>{crop.name}</option>
                ))}
              </select>
            </div>

            <div className="flex-1 overflow-y-auto p-4">
              {managerCropId && getVarietiesForCrop(managerCropId).length > 0 ? (
                <ul className="space-y-2">
                  {getVarietiesForCrop(managerCropId).map((v) => (
                    <li key={v.id} className="rounded border border-gray-200 p-3">
                      <div className="mb-2 flex items-center justify-between">
                        <span className="text-sm font-medium text-gray-900">{v.name}</span>
                        <button
                          onClick={() => handleDeleteVariety(v.id, v.name)}
                          className="text-red-400 hover:text-red-600 p-1"
                          title="削除"
                        >
                          <Trash2 className="h-4 w-4" />
                        </button>
                      </div>
                      <VarietyDefaultBoxesForm
                        varietyId={v.id}
                        initialValue={v.default_seedling_boxes_per_tan}
                        onSave={handleUpdateVarietyDefaultBoxes}
                      />
                    </li>
                  ))}
                </ul>
              ) : (
                <p className="text-gray-500 text-sm text-center py-4">品種が登録されていません</p>
              )}
            </div>

            <div className="p-4 border-t">
              <VarietyAddForm cropId={managerCropId} onAdd={async (name) => {
                if (!managerCropId) return;
                try {
                  await api.post('/plans/varieties/', { crop: managerCropId, name });
                  await fetchData(true);
                } catch (error: any) {
                  if (error.response?.status === 400) {
                    alert('この品種名は既に登録されています');
                  } else {
                    alert('品種の追加に失敗しました');
                  }
                }
              }} />
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function VarietyAddForm({ cropId, onAdd }: { cropId: number | null; onAdd: (name: string) => Promise<void> }) {
  const [name, setName] = useState('');
  const [adding, setAdding] = useState(false);

  const handleSubmit = async () => {
    const trimmed = name.trim();
    if (!trimmed) return;
    setAdding(true);
    await onAdd(trimmed);
    setName('');
    setAdding(false);
  };

  return (
    <div className="flex items-center gap-2">
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        onKeyDown={(e) => { if (e.key === 'Enter') handleSubmit(); }}
        placeholder="新しい品種名"
        disabled={!cropId || adding}
        className="flex-1 px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 disabled:opacity-50"
      />
      <button
        onClick={handleSubmit}
        disabled={!cropId || !name.trim() || adding}
        className="px-3 py-2 bg-green-600 text-white rounded-md text-sm hover:bg-green-700 disabled:opacity-50"
      >
        {adding ? '追加中...' : '追加'}
      </button>
    </div>
  );
}

function VarietyDefaultBoxesForm({
  varietyId,
  initialValue,
  onSave,
}: {
  varietyId: number;
  initialValue: string;
  onSave: (varietyId: number, defaultBoxes: string) => Promise<void>;
}) {
  const [value, setValue] = useState(initialValue);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    setValue(initialValue);
  }, [initialValue]);

  const handleSave = async () => {
    setSaving(true);
    await onSave(varietyId, value);
    setSaving(false);
  };

  return (
    <div className="flex items-end gap-2">
      <div className="flex-1">
        <label className="mb-1 block text-xs text-gray-600">反当苗箱枚数デフォルト</label>
        <input
          value={value}
          onChange={(e) => setValue(e.target.value)}
          className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-green-500"
          inputMode="decimal"
        />
      </div>
      <button
        onClick={handleSave}
        disabled={saving}
        className="rounded-md bg-green-600 px-3 py-2 text-sm text-white hover:bg-green-700 disabled:opacity-50"
      >
        保存
      </button>
    </div>
  );
}
