import { useState, useMemo, useRef, useCallback } from 'react';
import { useStore } from '../store';
import { getAvailableMonths, filterByMonth } from '../utils/bookkeeping';

// 列定義
const COLUMNS = [
  { key: 'date',        label: '日付',     defaultWidth: 96,  align: 'left'  },
  { key: 'desc',        label: '摘要',     defaultWidth: 200, align: 'left'  },
  { key: 'debitAcc',   label: '借方勘定', defaultWidth: 130, align: 'left'  },
  { key: 'debitAmt',   label: '借方金額', defaultWidth: 90,  align: 'right' },
  { key: 'creditAcc',  label: '貸方勘定', defaultWidth: 130, align: 'left'  },
  { key: 'creditAmt',  label: '貸方金額', defaultWidth: 90,  align: 'right' },
  { key: 'mfcat',      label: 'MF分類',   defaultWidth: 140, align: 'left'  },
] as const;

type ColKey = typeof COLUMNS[number]['key'];

function useColumnResize(defaults: Record<ColKey, number>) {
  const [widths, setWidths] = useState<Record<ColKey, number>>(defaults);
  const dragging = useRef<{ key: ColKey; startX: number; startW: number } | null>(null);

  const onMouseDown = useCallback((key: ColKey, e: React.MouseEvent) => {
    e.preventDefault();
    dragging.current = { key, startX: e.clientX, startW: widths[key] };

    const onMove = (ev: MouseEvent) => {
      if (!dragging.current) return;
      const delta = ev.clientX - dragging.current.startX;
      const newW = Math.max(50, dragging.current.startW + delta);
      setWidths(prev => ({ ...prev, [dragging.current!.key]: newW }));
    };
    const onUp = () => {
      dragging.current = null;
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseup', onUp);
    };
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseup', onUp);
  }, [widths]);

  return { widths, onMouseDown };
}

const DEFAULT_WIDTHS = Object.fromEntries(
  COLUMNS.map(c => [c.key, c.defaultWidth])
) as Record<ColKey, number>;

export default function JournalPage() {
  const { transactions, accounts, selectedMonth, setSelectedMonth } = useStore();
  const accountMap = useMemo(() => new Map(accounts.map(a => [a.id, a])), [accounts]);

  const availableMonths = useMemo(() => getAvailableMonths(transactions), [transactions]);
  const effectiveMonth = selectedMonth || availableMonths[0] || '';
  const [search, setSearch] = useState('');

  const { widths, onMouseDown } = useColumnResize(DEFAULT_WIDTHS);

  const [year, month] = effectiveMonth
    ? [parseInt(effectiveMonth.split('-')[0]), parseInt(effectiveMonth.split('-')[1])]
    : [0, 0];

  const filtered = useMemo(() => {
    let txs = effectiveMonth ? filterByMonth(transactions, year, month) : transactions;
    if (search) {
      const q = search.toLowerCase();
      txs = txs.filter(
        t => t.description.toLowerCase().includes(q) ||
          t.mfCategory?.includes(q) ||
          t.mfSubCategory?.includes(q) ||
          t.entries.some(e => accountMap.get(e.accountId)?.name.toLowerCase().includes(q))
      );
    }
    return [...txs].reverse();
  }, [transactions, effectiveMonth, year, month, search]);

  if (transactions.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center h-full text-slate-500">
        <p className="text-5xl mb-4">📒</p>
        <p className="text-slate-400">データがありません。CSVをインポートしてください。</p>
      </div>
    );
  }

  return (
    <div className="p-6 space-y-4">
      <div className="flex items-center justify-between">
        <h2 className="text-xl font-bold text-slate-100">仕訳帳</h2>
        <div className="flex gap-2">
          <input
            type="text"
            placeholder="検索..."
            value={search}
            onChange={e => setSearch(e.target.value)}
            className="border rounded-md px-3 py-1.5 text-sm w-48"
          />
          <select
            value={effectiveMonth}
            onChange={e => setSelectedMonth(e.target.value)}
            className="border rounded-md px-3 py-1.5 text-sm"
          >
            <option value="">全期間</option>
            {availableMonths.map(m => (
              <option key={m} value={m}>{m.replace('-', '年')}月</option>
            ))}
          </select>
        </div>
      </div>

      <p className="text-sm text-slate-400">{filtered.length}件</p>

      <div className="card p-0 overflow-auto">
        <table className="border-collapse" style={{ tableLayout: 'fixed', width: Object.values(widths).reduce((a, b) => a + b, 0) }}>
          <colgroup>
            {COLUMNS.map(col => (
              <col key={col.key} style={{ width: widths[col.key] }} />
            ))}
          </colgroup>

          <thead className="bg-slate-900 border-b border-slate-700 sticky top-0 z-10">
            <tr>
              {COLUMNS.map((col, i) => (
                <th
                  key={col.key}
                  className="relative px-3 py-2 text-left text-xs font-semibold text-slate-400 uppercase tracking-wider select-none"
                  style={{ width: widths[col.key] }}
                >
                  <span className={col.align === 'right' ? 'block text-right' : ''}>
                    {col.label}
                  </span>
                  {/* リサイズハンドル（最後の列以外） */}
                  {i < COLUMNS.length - 1 && (
                    <div
                      onMouseDown={e => onMouseDown(col.key, e)}
                      className="absolute top-0 right-0 h-full w-3 flex items-center justify-center cursor-col-resize group"
                    >
                      <div className="w-0.5 h-4 bg-slate-600 group-hover:bg-indigo-400 group-hover:w-1 transition-all rounded-full" />
                    </div>
                  )}
                </th>
              ))}
            </tr>
          </thead>

          <tbody className="divide-y divide-slate-700/50">
            {filtered.map(tx => {
              const debits  = tx.entries.filter(e => e.debit  > 0);
              const credits = tx.entries.filter(e => e.credit > 0);
              const maxRows = Math.max(debits.length, credits.length);

              return Array.from({ length: maxRows }, (_, i) => (
                <tr key={`${tx.id}-${i}`} className="hover:bg-slate-700/30">
                  {i === 0 && (
                    <>
                      <td className="px-3 py-2 text-sm text-slate-400 align-top overflow-hidden" rowSpan={maxRows}>
                        <span className="block truncate">{tx.date}</span>
                      </td>
                      <td className="px-3 py-2 text-sm align-top overflow-hidden" rowSpan={maxRows}>
                        <div className="font-medium text-slate-200 text-xs truncate">{tx.description}</div>
                        {tx.mfMemo && <div className="text-slate-500 text-xs truncate">{tx.mfMemo}</div>}
                      </td>
                    </>
                  )}
                  <td className="px-3 py-2 text-sm text-indigo-400 overflow-hidden">
                    <span className="block truncate">{debits[i] ? accountMap.get(debits[i].accountId)?.name : ''}</span>
                  </td>
                  <td className="px-3 py-2 text-sm text-right font-medium text-slate-200 overflow-hidden">
                    {debits[i] ? debits[i].debit.toLocaleString() : ''}
                  </td>
                  <td className="px-3 py-2 text-sm text-rose-400 overflow-hidden">
                    <span className="block truncate">{credits[i] ? accountMap.get(credits[i].accountId)?.name : ''}</span>
                  </td>
                  <td className="px-3 py-2 text-sm text-right font-medium text-slate-200 overflow-hidden">
                    {credits[i] ? credits[i].credit.toLocaleString() : ''}
                  </td>
                  {i === 0 && (
                    <td className="px-3 py-2 text-xs text-slate-500 align-top overflow-hidden" rowSpan={maxRows}>
                      <span className="block truncate">
                        {[tx.mfCategory, tx.mfSubCategory].filter(Boolean).join(' / ')}
                      </span>
                    </td>
                  )}
                </tr>
              ));
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}
