'use client';

/**
 * 분개 수정 팝업
 *
 * - 세금계산서 정보 (읽기전용): 구분, 거래처, 공급가액, 세액
 * - 분개 내역 테이블: 구분(차변/대변), 계정과목 Select, 차변 금액, 대변 금액
 * - 동적 행 추가/삭제 + 합계 행
 * - 버튼: 분개 삭제, 취소, 분개 수정
 */

import { useState, useCallback, useEffect, useMemo } from 'react';
import { toast } from 'sonner';
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 {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
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 {
  getJournalEntries,
  updateJournalEntry,
  deleteJournalEntry,
} from './actions';
import type { TaxInvoiceMgmtRecord, JournalEntryRow, JournalSide } from './types';
import {
  TAB_OPTIONS,
  JOURNAL_SIDE_OPTIONS,
  ACCOUNT_SUBJECT_OPTIONS,
} from './types';

interface JournalEntryModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  invoice: TaxInvoiceMgmtRecord;
  onSuccess: () => void;
}

function createEmptyRow(): JournalEntryRow {
  return {
    id: crypto.randomUUID(),
    side: 'debit',
    accountSubject: '',
    debitAmount: 0,
    creditAmount: 0,
  };
}

export function JournalEntryModal({
  open,
  onOpenChange,
  invoice,
  onSuccess,
}: JournalEntryModalProps) {
  const [rows, setRows] = useState<JournalEntryRow[]>([createEmptyRow()]);
  const [isLoading, setIsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);

  // 기존 분개 내역 로드
  useEffect(() => {
    if (!open || !invoice) return;

    const loadEntries = async () => {
      setIsLoading(true);
      try {
        const result = await getJournalEntries(invoice.id);
        if (result.success && result.data && result.data.rows.length > 0) {
          setRows(
            result.data.rows.map((r) => ({
              id: crypto.randomUUID(),
              side: r.side as JournalSide,
              accountSubject: r.account_subject,
              debitAmount: r.debit_amount,
              creditAmount: r.credit_amount,
            }))
          );
        } else {
          // 기본 행 2개 (차변/대변)
          setRows([
            { ...createEmptyRow(), side: 'debit', debitAmount: invoice.totalAmount },
            { ...createEmptyRow(), side: 'credit', creditAmount: invoice.totalAmount },
          ]);
        }
      } catch {
        setRows([
          { ...createEmptyRow(), side: 'debit', debitAmount: invoice.totalAmount },
          { ...createEmptyRow(), side: 'credit', creditAmount: invoice.totalAmount },
        ]);
      } finally {
        setIsLoading(false);
      }
    };

    loadEntries();
  }, [open, invoice]);

  // 행 추가
  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);
    return { debitTotal, creditTotal };
  }, [rows]);

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

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

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

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

  const divisionLabel =
    TAB_OPTIONS.find((t) => t.value === invoice.division)?.label || invoice.division;

  return (
    <>
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent className="sm:max-w-[700px] max-h-[85vh] flex flex-col">
          <DialogHeader>
            <DialogTitle>분개 수정</DialogTitle>
          </DialogHeader>

          {/* 세금계산서 정보 (읽기전용) */}
          <div className="space-y-2 p-3 border rounded-lg">
            <Label className="text-sm font-semibold">세금계산서 정보</Label>
          <div className="grid grid-cols-4 gap-3 text-sm">
            <div>
              <Label className="text-xs text-muted-foreground">구분</Label>
              <div className="font-medium">{divisionLabel}</div>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">거래처</Label>
              <div className="font-medium">{invoice.vendorName}</div>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">공급가액</Label>
              <div className="font-medium">{formatNumber(invoice.supplyAmount)}원</div>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">세액</Label>
              <div className="font-medium">{formatNumber(invoice.taxAmount)}원</div>
            </div>
          </div>
          </div>

          {/* 분개 내역 */}
          <div className="space-y-2 p-3 border rounded-lg flex-1 overflow-auto">
            <Label className="text-sm font-semibold">분개 내역</Label>

          <div className="overflow-auto border rounded-md">
            {isLoading ? (
              <div className="flex items-center justify-center h-[150px] text-sm text-muted-foreground">
                로딩 중...
              </div>
            ) : (
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead className="text-center w-[100px]">구분</TableHead>
                    <TableHead>계정과목</TableHead>
                    <TableHead className="text-right w-[140px]">차변 금액</TableHead>
                    <TableHead className="text-right w-[140px]">대변 금액</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {rows.map((row) => (
                    <TableRow key={row.id}>
                      <TableCell className="p-1">
                        <Select
                          value={row.side}
                          onValueChange={(v) => handleRowChange(row.id, 'side', v)}
                        >
                          <SelectTrigger className="h-8 text-sm">
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            {JOURNAL_SIDE_OPTIONS.map((opt) => (
                              <SelectItem key={opt.value} value={opt.value}>
                                {opt.label}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </TableCell>
                      <TableCell className="p-1">
                        <Select
                          value={row.accountSubject}
                          onValueChange={(v) =>
                            handleRowChange(row.id, 'accountSubject', v)
                          }
                        >
                          <SelectTrigger className="h-8 text-sm">
                            <SelectValue placeholder="선택" />
                          </SelectTrigger>
                          <SelectContent>
                            {ACCOUNT_SUBJECT_OPTIONS.filter((o) => o.value).map(
                              (opt) => (
                                <SelectItem key={opt.value} value={opt.value}>
                                  {opt.label}
                                </SelectItem>
                              )
                            )}
                          </SelectContent>
                        </Select>
                      </TableCell>
                      <TableCell className="p-1">
                        <Input
                          type="number"
                          value={row.debitAmount || ''}
                          onChange={(e) =>
                            handleRowChange(
                              row.id,
                              'debitAmount',
                              Number(e.target.value) || 0
                            )
                          }
                          disabled={row.side === 'credit'}
                          className="h-8 text-sm text-right"
                          placeholder="0"
                        />
                      </TableCell>
                      <TableCell className="p-1">
                        <Input
                          type="number"
                          value={row.creditAmount || ''}
                          onChange={(e) =>
                            handleRowChange(
                              row.id,
                              'creditAmount',
                              Number(e.target.value) || 0
                            )
                          }
                          disabled={row.side === 'debit'}
                          className="h-8 text-sm text-right"
                          placeholder="0"
                        />
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
                <TableFooter>
                  <TableRow className="bg-muted/50 font-medium">
                    <TableCell colSpan={2} 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>
                  </TableRow>
                </TableFooter>
              </Table>
            )}
          </div>
          </div>

          {/* 차대변 불일치 경고 */}
          {totals.debitTotal !== totals.creditTotal && (
            <p className="text-xs text-red-500">
              차변 합계({formatNumber(totals.debitTotal)})와 대변 합계(
              {formatNumber(totals.creditTotal)})가 일치하지 않습니다.
            </p>
          )}

          <DialogFooter className="gap-2">
            <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>
    </>
  );
}
