'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { Plus, X, ChevronUp, ChevronDown, Pencil, Check } from 'lucide-react';
import Navbar from '@/components/Navbar';
import { DistributionPlan, FertilizationPlan } from '@/types';
import { api } from '@/lib/api';

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

// ローカル管理用のグループ型（ID未採番の新規グループも持てる）
interface LocalGroup {
  tempId: string;
  name: string;
  order: number;
  fieldIds: number[];
  isRenamingName?: string; // 名前変更中の一時値
}

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

interface Props {
  planId?: number; // 編集時のみ
}

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

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

  // 施肥計画一覧（セレクタ用）
  const [fertilizationPlans, setFertilizationPlans] = useState<FertilizationPlan[]>([]);
  // 選択中の施肥計画の詳細（肥料・entries）
  const [fertPlanDetail, setFertPlanDetail] = useState<DistributionPlan['fertilization_plan'] | null>(null);

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

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

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

  useEffect(() => {
    const init = async () => {
      try {
        // 施肥計画一覧を全年度取得（分配計画のベースになる）
        const res = await api.get('/fertilizer/plans/');
        setFertilizationPlans(res.data);
      } catch (e) {
        console.error(e);
      }

      if (isEdit && planId) {
        try {
          // 既存の分配計画を読み込む
          const detailRes = await api.get(`/fertilizer/distribution/${planId}/`);
          const detail: DistributionPlan = detailRes.data;
          setName(detail.name);
          setFertilizationPlanId(detail.fertilization_plan.id);
          setFertPlanDetail(detail.fertilization_plan);
          // グループを 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),
            }))
          );
        } catch (e) {
          console.error(e);
        }
      }
      setLoading(false);
    };
    init();
  }, [planId]);

  // 施肥計画が変わったら詳細を取得
  useEffect(() => {
    if (!fertilizationPlanId) {
      setFertPlanDetail(null);
      if (!isEdit) setGroups([]);
      return;
    }
    if (isEdit && fertPlanDetail?.id === fertilizationPlanId) return;

    const fetchDetail = async () => {
      try {
        const res = await api.get(`/fertilizer/plans/${fertilizationPlanId}/`);
        const data: FertilizationPlan = res.data;
        // FertilizationPlanForDistributionSerializer と同じ構造に合わせる
        const ferts = Array.from(
          new Map(
            data.entries.map(e => [e.fertilizer, { id: e.fertilizer, name: e.fertilizer_name || '' }])
          ).values()
        ).sort((a, b) => a.name.localeCompare(b.name));
        setFertPlanDetail({
          id: data.id,
          name: data.name,
          year: data.year,
          variety_name: data.variety_name,
          crop_name: data.crop_name,
          fertilizers: ferts,
          entries: data.entries.map(e => ({
            field: e.field,
            fertilizer: e.fertilizer,
            bags: String(e.bags),
          })),
        });
        if (!isEdit) setGroups([]);
      } catch (e) {
        console.error(e);
      }
    };
    fetchDetail();
  }, [fertilizationPlanId]);

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

  // 全圃場一覧（施肥計画のentries に含まれる圃場）
  const allPlanFields: FieldInfo[] = (() => {
    if (!fertPlanDetail) return [];
    const seen = new Map<number, FieldInfo>();
    for (const e of fertPlanDetail.entries) {
      if (!seen.has(e.field)) {
        // field名は後述の fertilizationPlans から取る
        seen.set(e.field, { id: e.field, name: String(e.field), area_tan: '0' });
      }
    }
    return Array.from(seen.values());
  })();

  // fertilizationPlans から field情報を取得（FertilizationPlanSerializer の entries に field_name が含まれる）
  const fieldInfoMap = (() => {
    const map = new Map<number, FieldInfo>();
    if (!fertPlanDetail) return map;
    const plan = fertilizationPlans.find(p => p.id === fertPlanDetail.id);
    if (plan) {
      for (const e of plan.entries) {
        if (e.field && !map.has(e.field)) {
          map.set(e.field, {
            id: e.field,
            name: e.field_name || String(e.field),
            area_tan: e.field_area_tan || '0',
          });
        }
      }
    }
    return map;
  })();

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

  // 割り当て済みフィールドIDセット
  const assignedFieldIds = new Set(groups.flatMap(g => g.fieldIds));

  // 未割り当て圃場
  const unassignedFields = fertPlanDetail
    ? Array.from(
        new Map(
          fertPlanDetail.entries
            .map(e => e.field)
            .filter(id => !assignedFieldIds.has(id))
            .map(id => [id, getFieldInfo(id)])
        ).values()
      )
    : [];

  // bags取得
  const getBags = (fieldId: number, fertilizerId: number): number => {
    if (!fertPlanDetail) return 0;
    const entry = fertPlanDetail.entries.find(
      e => e.field === fieldId && e.fertilizer === fertilizerId
    );
    return entry ? parseFloat(entry.bags) : 0;
  };

  // グループごとの集計
  const groupSummaries = groups.map(g => {
    const fertTotals = (fertPlanDetail?.fertilizers || []).map(fert => ({
      fertilizerId: fert.id,
      fertilizerName: fert.name,
      total: g.fieldIds.reduce((sum, fId) => sum + getBags(fId, fert.id), 0),
    }));
    const rowTotal = fertTotals.reduce((s, f) => s + f.total, 0);
    return { ...g, fertTotals, rowTotal };
  });

  // 未割り当てグループの集計
  const unassignedSummary = {
    fertTotals: (fertPlanDetail?.fertilizers || []).map(fert => ({
      fertilizerId: fert.id,
      fertilizerName: fert.name,
      total: unassignedFields.reduce((sum, f) => sum + getBags(f.id, fert.id), 0),
    })),
    rowTotal: 0 as number,
  };
  unassignedSummary.rowTotal = unassignedSummary.fertTotals.reduce((s, f) => s + f.total, 0);

  // 肥料合計行
  const fertColumnTotals = (fertPlanDetail?.fertilizers || []).map(fert => {
    const groupTotal = groupSummaries.reduce(
      (sum, g) => sum + (g.fertTotals.find(f => f.fertilizerId === fert.id)?.total || 0),
      0
    );
    const unassignedTotal = unassignedSummary.fertTotals.find(f => f.fertilizerId === fert.id)?.total || 0;
    return { id: fert.id, total: groupTotal + unassignedTotal };
  });
  const grandTotal = fertColumnTotals.reduce((s, f) => s + f.total, 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
      )
    );
  };

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

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

    setSaving(true);
    const payload = {
      name: name.trim(),
      fertilization_plan_id: fertilizationPlanId,
      groups: groups.map((g, i) => ({
        name: g.name,
        order: i,
        field_ids: g.fieldIds,
      })),
    };

    try {
      if (isEdit) {
        await api.put(`/fertilizer/distribution/${planId}/`, payload);
      } else {
        await api.post('/fertilizer/distribution/', 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-5xl mx-auto px-4 py-8 text-gray-500 text-sm">読み込み中...</main>
      </div>
    );
  }

  const fertilizers = fertPlanDetail?.fertilizers || [];

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

        <h1 className="text-xl font-bold text-gray-900 mb-6">
          {isEdit ? '分配計画を編集' : '分配計画を新規作成'}
        </h1>

        {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="例: 2025年コシヒカリ 分配計画"
                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 flex-1 min-w-64">
              <label className="text-sm font-medium text-gray-700 whitespace-nowrap">施肥計画</label>
              <select
                value={fertilizationPlanId}
                onChange={e => setFertilizationPlanId(e.target.value ? Number(e.target.value) : '')}
                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"
              >
                <option value="">-- 選択 --</option>
                {fertilizationPlans.map(p => (
                  <option key={p.id} value={p.id}>
                    {p.year}年 {p.name}（{p.crop_name}/{p.variety_name}）
                  </option>
                ))}
              </select>
            </div>
          </div>
        </div>

        {!fertPlanDetail ? (
          <div className="bg-white rounded-lg border border-gray-200 p-8 text-center text-gray-400 text-sm">
            施肥計画を選択するとグループ割り当て画面が表示されます
          </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 transition-colors"
                >
                  <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>
                          <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);
                          const bags = fertilizers.map(fert => getBags(fId, fert.id));
                          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"
                                title="グループから外す"
                              >
                                <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 w-16 text-right">{fi.area_tan}反</span>
                              <span className="text-gray-400 text-xs">
                                {fertilizers.map((fert, i) => (
                                  <span key={fert.id}>
                                    {i > 0 && ' / '}
                                    {fert.name}: {bags[i].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" title={fi.name}>{fi.name}</span>
                        <span className="text-gray-400 text-xs w-16 shrink-0 text-right">{fi.area_tan}反</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>

            {/* 集計プレビュー */}
            {(groups.length > 0 || unassignedFields.length > 0) && fertilizers.length > 0 && (
              <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="overflow-x-auto">
                  <table className="min-w-full text-sm border-collapse">
                    <thead>
                      <tr>
                        <th className="border border-gray-200 bg-gray-50 px-3 py-2 text-left font-medium text-gray-600 text-xs">グループ</th>
                        {fertilizers.map(fert => (
                          <th key={fert.id} className="border border-gray-200 bg-gray-50 px-3 py-2 text-right font-medium text-gray-600 text-xs">
                            {fert.name}
                          </th>
                        ))}
                        <th className="border border-gray-200 bg-gray-50 px-3 py-2 text-right font-medium text-gray-600 text-xs">合計（袋）</th>
                      </tr>
                    </thead>
                    <tbody>
                      {groupSummaries.map(g => (
                        <tr key={g.tempId} className="hover:bg-green-50">
                          <td className="border border-gray-200 px-3 py-2 font-medium text-gray-800">{g.name}</td>
                          {fertilizers.map(fert => {
                            const t = g.fertTotals.find(f => f.fertilizerId === fert.id)?.total || 0;
                            return (
                              <td key={fert.id} className="border border-gray-200 px-3 py-2 text-right text-gray-700">
                                {t > 0 ? t.toFixed(2) : <span className="text-gray-300">-</span>}
                              </td>
                            );
                          })}
                          <td className="border border-gray-200 px-3 py-2 text-right font-medium text-gray-800">
                            {g.rowTotal.toFixed(2)}
                          </td>
                        </tr>
                      ))}
                      {unassignedSummary.rowTotal > 0 && (
                        <tr className="bg-yellow-50">
                          <td className="border border-gray-200 px-3 py-2 text-gray-500 italic">未割り当て</td>
                          {fertilizers.map(fert => {
                            const t = unassignedSummary.fertTotals.find(f => f.fertilizerId === fert.id)?.total || 0;
                            return (
                              <td key={fert.id} className="border border-gray-200 px-3 py-2 text-right text-gray-500">
                                {t > 0 ? t.toFixed(2) : <span className="text-gray-300">-</span>}
                              </td>
                            );
                          })}
                          <td className="border border-gray-200 px-3 py-2 text-right text-gray-500">
                            {unassignedSummary.rowTotal.toFixed(2)}
                          </td>
                        </tr>
                      )}
                    </tbody>
                    <tfoot>
                      <tr className="font-bold bg-gray-50">
                        <td className="border border-gray-200 px-3 py-2 text-gray-800">合計</td>
                        {fertColumnTotals.map(f => (
                          <td key={f.id} className="border border-gray-200 px-3 py-2 text-right text-gray-800">
                            {f.total.toFixed(2)}
                          </td>
                        ))}
                        <td className="border border-gray-200 px-3 py-2 text-right text-gray-800">
                          {grandTotal.toFixed(2)}
                        </td>
                      </tr>
                    </tfoot>
                  </table>
                </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>
  );
}
