'use client';

/**
 * 분개 수정 팝업
 *
 * - 거래 정보 (읽기전용): 날짜, 구분, 금액, 적요, 계좌(은행명+계좌번호)
 * - 전표 적요: 적요 Input
 * - 분개 내역 테이블: 구분(차변/대변), 계정과목, 거래처, 차변 금액, 대변 금액, 적요, 삭제
 * - 합계 행 + 대차 균형 표시
 * - 버튼: 분개 삭제(왼쪽), 취소, 분개 수정
 */

import { useState, useCallback, useEffect, useMemo } from 'react';
import { toast } from 'sonner';
import { Plus, Trash2 } from 'lucide-react';
import { formatNumber } from '@/lib/utils/amount';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { CurrencyInput } from '@/components/ui/currency-input';
import { FormField } from '@/components/molecules/FormField';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { AccountSubjectSelect } from '@/components/accounting/common';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
  TableFooter,
} from '@/components/ui/table';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import {
  getJournalDetail,
  updateJournalDetail,
  deleteJournalDetail,
  getVendorList,
} from './actions';
import type {
  GeneralJournalRecord,
  JournalEntryRow,
  JournalSide,
  VendorOption,
} from './types';
import { JOURNAL_SIDE_OPTIONS, JOURNAL_DIVISION_LABELS } from './types';

interface JournalEditModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  record: GeneralJournalRecord;
  onSuccess: () => void;
}

function createEmptyRow(): JournalEntryRow {
  return {
    id: crypto.randomUUID(),
    side: 'debit',
    accountSubjectId: '',
    accountSubjectName: '',
    vendorId: '',
    vendorName: '',
    debitAmount: 0,
    creditAmount: 0,
    memo: '',
  };
}

export function JournalEditModal({
  open,
  onOpenChange,
  record,
  onSuccess,
}: JournalEditModalProps) {
  // 전표 적요
  const [journalMemo, setJournalMemo] = useState('');

  // 분개 행
  const [rows, setRows] = useState<JournalEntryRow[]>([createEmptyRow()]);
  const [isLoading, setIsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);

  // 거래 정보 (읽기전용)
  const [bankName, setBankName] = useState('');
  const [accountNumber, setAccountNumber] = useState('');

  // 옵션 데이터
  const [vendors, setVendors] = useState<VendorOption[]>([]);

  // 데이터 로드
  useEffect(() => {
    if (!open || !record) return;

    const loadData = async () => {
      setIsLoading(true);
      try {
        const [detailRes, vendorsRes] = await Promise.all([
          getJournalDetail(record.id),
          getVendorList(),
        ]);

        if (vendorsRes.success && vendorsRes.data) {
          setVendors(vendorsRes.data);
        }

        if (detailRes.success && detailRes.data) {
          const detail = detailRes.data;
          setBankName(detail.bank_name || '');
          setAccountNumber(detail.account_number || '');
          setJournalMemo(detail.journal_memo || '');

          if (detail.rows && detail.rows.length > 0) {
            setRows(
              detail.rows.map((r) => ({
                id: crypto.randomUUID(),
                side: r.side as JournalSide,
                accountSubjectId: String(r.account_subject_id),
                accountSubjectName: r.account_subject_name,
                vendorId: r.vendor_id ? String(r.vendor_id) : '',
                vendorName: r.vendor_name || '',
                debitAmount: r.debit_amount,
                creditAmount: r.credit_amount,
                memo: r.memo || '',
              }))
            );
          } else {
            setRows([
              { ...createEmptyRow(), side: 'debit', debitAmount: record.amount },
              { ...createEmptyRow(), side: 'credit', creditAmount: record.amount },
            ]);
          }
        } else {
          setRows([
            { ...createEmptyRow(), side: 'debit', debitAmount: record.amount },
            { ...createEmptyRow(), side: 'credit', creditAmount: record.amount },
          ]);
        }
      } catch {
        setRows([
          { ...createEmptyRow(), side: 'debit', debitAmount: record.amount },
          { ...createEmptyRow(), side: 'credit', creditAmount: record.amount },
        ]);
      } finally {
        setIsLoading(false);
      }
    };

    loadData();
  }, [open, record]);

  // 행 추가
  const handleAddRow = useCallback(() => {
    setRows((prev) => [...prev, createEmptyRow()]);
  }, []);

  // 행 삭제
  const handleRemoveRow = useCallback((rowId: string) => {
    setRows((prev) => {
      if (prev.length <= 1) return prev;
      return prev.filter((r) => r.id !== rowId);
    });
  }, []);

  // 행 수정
  const handleRowChange = useCallback(
    (rowId: string, field: keyof JournalEntryRow, value: string | number) => {
      setRows((prev) =>
        prev.map((r) => {
          if (r.id !== rowId) return r;
          const updated = { ...r, [field]: value };
          if (field === 'side') {
            if (value === 'debit') {
              updated.creditAmount = 0;
            } else {
              updated.debitAmount = 0;
            }
          }
          return updated;
        })
      );
    },
    []
  );

  // 합계
  const totals = useMemo(() => {
    const debitTotal = rows.reduce((sum, r) => sum + (r.debitAmount || 0), 0);
    const creditTotal = rows.reduce((sum, r) => sum + (r.creditAmount || 0), 0);
    const isBalanced = debitTotal === creditTotal;
    const difference = Math.abs(debitTotal - creditTotal);
    return { debitTotal, creditTotal, isBalanced, difference };
  }, [rows]);

  // 분개 수정
  const handleSave = useCallback(async () => {
    const hasEmptyAccount = rows.some((r) => !r.accountSubjectId);
    if (hasEmptyAccount) {
      toast.warning('모든 행의 계정과목을 선택해주세요.');
      return;
    }

    if (!totals.isBalanced) {
      toast.warning('차변 합계와 대변 합계가 일치하지 않습니다.');
      return;
    }

    setIsSaving(true);
    try {
      const result = await updateJournalDetail(record.id, {
        journalMemo,
        rows,
      });
      if (result.success) {
        toast.success('분개가 수정되었습니다.');
        onSuccess();
      } else {
        toast.error(result.error || '분개 수정에 실패했습니다.');
      }
    } catch {
      toast.error('서버 오류가 발생했습니다.');
    } finally {
      setIsSaving(false);
    }
  }, [record.id, journalMemo, rows, totals, onSuccess]);

  // 분개 삭제
  const handleDelete = useCallback(async () => {
    setShowDeleteConfirm(false);
    try {
      const result = await deleteJournalDetail(record.id);
      if (result.success) {
        toast.success('분개가 삭제되었습니다.');
        onSuccess();
      } else {
        toast.error(result.error || '분개 삭제에 실패했습니다.');
      }
    } catch {
      toast.error('서버 오류가 발생했습니다.');
    }
  }, [record.id, onSuccess]);

  return (
    <>
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent className="sm:max-w-[850px] max-h-[85vh] flex flex-col">
          <DialogHeader>
            <DialogTitle>분개 수정</DialogTitle>
            <DialogDescription className="sr-only">전표의 분개 내역을 수정합니다</DialogDescription>
          </DialogHeader>

          {/* 거래 정보 (읽기전용) */}
          <div className="grid grid-cols-2 sm:grid-cols-5 gap-3 p-3 bg-muted/50 rounded-lg text-sm">
            <div>
              <Label className="text-xs text-muted-foreground">날짜</Label>
              <div className="font-medium">{record.date}</div>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">구분</Label>
              <div className="font-medium">
                {JOURNAL_DIVISION_LABELS[record.division] || record.division}
              </div>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">금액</Label>
              <div className="font-medium">{formatNumber(record.amount)}원</div>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">적요</Label>
              <div className="font-medium truncate">{record.description || '-'}</div>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">계좌</Label>
              <div className="font-medium truncate">
                {bankName && accountNumber ? `${bankName} ${accountNumber}` : '-'}
              </div>
            </div>
          </div>

          {/* 전표 적요 */}
          <FormField
            label="전표 적요"
            value={journalMemo}
            onChange={setJournalMemo}
            placeholder="적요 입력"
          />

          {/* 분개 내역 헤더 */}
          <div className="flex items-center justify-between">
            <Label className="text-sm font-semibold">분개 내역</Label>
            <Button variant="outline" size="sm" onClick={handleAddRow}>
              <Plus className="h-4 w-4 mr-1" />
              행 추가
            </Button>
          </div>

          {/* 분개 테이블 */}
          <div className="flex-1 min-h-0 max-h-[40vh] overflow-auto border rounded-md">
            {isLoading ? (
              <div className="flex items-center justify-center h-[150px] text-sm text-muted-foreground">
                로딩 중...
              </div>
            ) : (
              <Table className="min-w-[750px]">
                <TableHeader>
                  <TableRow>
                    <TableHead className="text-center w-[90px]">구분</TableHead>
                    <TableHead className="w-[150px]">계정과목</TableHead>
                    <TableHead className="w-[140px]">거래처</TableHead>
                    <TableHead className="text-right w-[120px]">차변 금액</TableHead>
                    <TableHead className="text-right w-[120px]">대변 금액</TableHead>
                    <TableHead className="w-[120px]">적요</TableHead>
                    <TableHead className="text-center w-[50px]"></TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {rows.map((row) => (
                    <TableRow key={row.id}>
                      <TableCell className="p-1">
                        <div className="flex">
                          {JOURNAL_SIDE_OPTIONS.map((opt) => (
                            <Button
                              key={opt.value}
                              type="button"
                              size="sm"
                              variant={row.side === opt.value ? 'default' : 'outline'}
                              className="h-7 px-2 text-xs flex-1 rounded-none first:rounded-l-md last:rounded-r-md"
                              onClick={() => handleRowChange(row.id, 'side', opt.value)}
                            >
                              {opt.label}
                            </Button>
                          ))}
                        </div>
                      </TableCell>
                      <TableCell className="p-1">
                        <AccountSubjectSelect
                          value={row.accountSubjectId}
                          onValueChange={(v) =>
                            handleRowChange(row.id, 'accountSubjectId', v)
                          }
                          size="sm"
                          placeholder="선택"
                        />
                      </TableCell>
                      <TableCell className="p-1">
                        <Select
                          value={row.vendorId || 'none'}
                          onValueChange={(v) =>
                            handleRowChange(row.id, 'vendorId', v === 'none' ? '' : v)
                          }
                        >
                          <SelectTrigger className="h-8 text-sm">
                            <SelectValue placeholder="선택" />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="none">선택</SelectItem>
                            {vendors.map((v) => (
                              <SelectItem key={v.id} value={v.id}>
                                {v.name}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </TableCell>
                      <TableCell className="p-1">
                        <CurrencyInput
                          value={row.debitAmount || 0}
                          onChange={(v) =>
                            handleRowChange(row.id, 'debitAmount', v ?? 0)
                          }
                          disabled={row.side === 'credit'}
                          className="h-8 text-sm"
                          showCurrency={false}
                        />
                      </TableCell>
                      <TableCell className="p-1">
                        <CurrencyInput
                          value={row.creditAmount || 0}
                          onChange={(v) =>
                            handleRowChange(row.id, 'creditAmount', v ?? 0)
                          }
                          disabled={row.side === 'debit'}
                          className="h-8 text-sm"
                          showCurrency={false}
                        />
                      </TableCell>
                      <TableCell className="p-1">
                        <Input
                          value={row.memo}
                          onChange={(e) => handleRowChange(row.id, 'memo', e.target.value)}
                          className="h-8 text-sm"
                          placeholder="적요"
                        />
                      </TableCell>
                      <TableCell className="p-1 text-center">
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-7 w-7 text-red-500 hover:text-red-600 hover:bg-red-50"
                          onClick={() => handleRemoveRow(row.id)}
                          disabled={rows.length <= 1}
                        >
                          <Trash2 className="h-3.5 w-3.5" />
                        </Button>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
                <TableFooter>
                  <TableRow className="bg-muted/50 font-medium">
                    <TableCell colSpan={3} className="text-right text-sm">
                      합계
                    </TableCell>
                    <TableCell className="text-right text-sm font-bold">
                      {formatNumber(totals.debitTotal)}
                    </TableCell>
                    <TableCell className="text-right text-sm font-bold">
                      {formatNumber(totals.creditTotal)}
                    </TableCell>
                    <TableCell colSpan={2} className="text-center text-sm">
                      {totals.isBalanced ? (
                        <span className="text-green-600 font-medium">대차 균형</span>
                      ) : (
                        <span className="text-red-500 font-medium">
                          차이: {formatNumber(totals.difference)}원
                        </span>
                      )}
                    </TableCell>
                  </TableRow>
                </TableFooter>
              </Table>
            )}
          </div>

          <DialogFooter className="gap-3">
            <Button
              variant="destructive"
              onClick={() => setShowDeleteConfirm(true)}
              className="mr-auto"
            >
              분개 삭제
            </Button>
            <Button variant="outline" onClick={() => onOpenChange(false)}>
              취소
            </Button>
            <Button onClick={handleSave} disabled={isSaving}>
              {isSaving ? '저장 중...' : '분개 수정'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 분개 삭제 확인 */}
      <AlertDialog open={showDeleteConfirm} onOpenChange={setShowDeleteConfirm}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>분개 삭제</AlertDialogTitle>
            <AlertDialogDescription>
              이 전표의 분개 내역을 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>취소</AlertDialogCancel>
            <AlertDialogAction
              onClick={handleDelete}
              className="bg-red-500 hover:bg-red-600"
            >
              삭제
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  );
}
