'use client';

/**
 * 일반전표입력 - 메인 리스트 페이지
 *
 * 기획서 기준:
 * - 날짜범위 + 기간버튼(이번달, 1년전, D-2일~D-5일) + 검색 Input
 * - 요약: 4개 통계값 (전입 건수/금액, 전출 건수/금액)
 * - 버튼: 계정과목 설정, 수기 전표 입력
 * - 테이블 10컬럼: 날짜, 적요, 입금, 출금, 잔액, 분개, 내역, 차변, 대변, 분개(버튼)
 * - tableFooter: 합계 행 + 범례(수기/연동)
 */

import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
import { toast } from 'sonner';
import { FileText, Settings, PenLine, Search } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { TableRow, TableCell } from '@/components/ui/table';
import {
  UniversalListPage,
  type UniversalListConfig,
  type SelectionHandlers,
  type RowClickHandlers,
  type StatCard,
} from '@/components/templates/UniversalListPage';
import { MobileCard } from '@/components/organisms/MobileCard';
import { ScrollableButtonGroup } from '@/components/atoms/ScrollableButtonGroup';
import { getJournalEntries, getJournalSummary } from './actions';
import { AccountSubjectSettingModal } from '@/components/accounting/common';
import { ManualJournalEntryModal } from './ManualJournalEntryModal';
import { JournalEditModal } from './JournalEditModal';
import type { GeneralJournalRecord, GeneralJournalSummary, PeriodButtonValue } from './types';
import {
  PERIOD_BUTTONS,
  JOURNAL_DIVISION_LABELS,
  getPeriodDates,
} from './types';
import { formatNumber } from '@/lib/utils/amount';
import { invalidateDashboard } from '@/lib/dashboard-invalidation';

// ===== 테이블 컬럼 (기획서 기준 10개) =====
const tableColumns = [
  { key: 'date', label: '날짜', className: 'text-center w-[100px]', copyable: true },
  { key: 'description', label: '적요', className: 'w-[140px]', copyable: true },
  { key: 'depositAmount', label: '입금', className: 'text-right w-[100px]', copyable: true },
  { key: 'withdrawalAmount', label: '출금', className: 'text-right w-[100px]', copyable: true },
  { key: 'balance', label: '잔액', className: 'text-right w-[100px]', copyable: true },
  { key: 'division', label: '구분', className: 'text-center w-[70px]', copyable: true },
  { key: 'journalDescription', label: '내역', className: 'w-[100px]', copyable: true },
  { key: 'debitAmount', label: '차변', className: 'text-right w-[90px]', copyable: true },
  { key: 'creditAmount', label: '대변', className: 'text-right w-[90px]', copyable: true },
  { key: 'journalAction', label: '분개', className: 'text-center w-[70px]', sortable: false },
];

export function GeneralJournalEntry() {
  // ===== 필터 상태 =====
  const defaultPeriod = getPeriodDates('this_month');
  const [selectedPeriod, setSelectedPeriod] = useState<PeriodButtonValue>('this_month');
  const [startDate, setStartDate] = useState(defaultPeriod.start);
  const [endDate, setEndDate] = useState(defaultPeriod.end);
  const [searchKeyword, setSearchKeyword] = useState('');

  // ===== 데이터 상태 =====
  const [journalData, setJournalData] = useState<GeneralJournalRecord[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const isInitialLoadDone = useRef(false);
  const [currentPage, setCurrentPage] = useState(1);
  const [pagination, setPagination] = useState({
    currentPage: 1,
    lastPage: 1,
    perPage: 20,
    total: 0,
  });

  // ===== 요약 상태 =====
  const [summary, setSummary] = useState<GeneralJournalSummary>({
    totalCount: 0,
    depositCount: 0,
    depositAmount: 0,
    withdrawalCount: 0,
    withdrawalAmount: 0,
    journalCompleteCount: 0,
    journalIncompleteCount: 0,
  });

  // ===== 모달 상태 =====
  const [showAccountSetting, setShowAccountSetting] = useState(false);
  const [showManualEntry, setShowManualEntry] = useState(false);
  const [journalEditTarget, setJournalEditTarget] = useState<GeneralJournalRecord | null>(null);

  // ===== 기간 버튼 클릭 =====
  const handlePeriodClick = useCallback((period: PeriodButtonValue) => {
    setSelectedPeriod(period);
    const dates = getPeriodDates(period);
    setStartDate(dates.start);
    setEndDate(dates.end);
    setCurrentPage(1);
  }, []);

  // ===== 데이터 로드 =====
  const loadData = useCallback(async () => {
    if (!isInitialLoadDone.current) {
      setIsLoading(true);
    }
    try {
      const [listResult, summaryResult] = await Promise.all([
        getJournalEntries({
          startDate,
          endDate,
          search: searchKeyword,
          page: currentPage,
          perPage: 20,
        }),
        getJournalSummary({
          startDate,
          endDate,
          search: searchKeyword,
        }),
      ]);

      if (listResult.success) {
        setJournalData(listResult.data);
        setPagination(listResult.pagination);
      } else {
        toast.error(listResult.error || '목록 조회에 실패했습니다.');
      }

      if (summaryResult.success && summaryResult.data) {
        setSummary(summaryResult.data);
      }
    } catch {
      toast.error('서버 오류가 발생했습니다.');
    } finally {
      setIsLoading(false);
      isInitialLoadDone.current = true;
    }
  }, [startDate, endDate, searchKeyword, currentPage]);

  useEffect(() => {
    loadData();
  }, [loadData]);

  // ===== 조회 버튼 =====
  const handleSearch = useCallback(() => {
    setCurrentPage(1);
    loadData();
  }, [loadData]);

  // ===== 수기 등록 완료 =====
  const handleManualEntrySuccess = useCallback(() => {
    setShowManualEntry(false);
    loadData();
    invalidateDashboard('journalEntry');
  }, [loadData]);

  // ===== 분개 수정 완료 =====
  const handleJournalEditSuccess = useCallback(() => {
    setJournalEditTarget(null);
    loadData();
    invalidateDashboard('journalEntry');
  }, [loadData]);

  // ===== 합계 계산 =====
  const tableTotals = useMemo(() => ({
    depositTotal: journalData.reduce((sum, r) => sum + (r.depositAmount || 0), 0),
    withdrawalTotal: journalData.reduce((sum, r) => sum + (r.withdrawalAmount || 0), 0),
    debitTotal: journalData.reduce((sum, r) => sum + (r.debitAmount || 0), 0),
    creditTotal: journalData.reduce((sum, r) => sum + (r.creditAmount || 0), 0),
  }), [journalData]);

  // ===== UniversalListPage Config =====
  const config: UniversalListConfig<GeneralJournalRecord> = useMemo(
    () => ({
      title: '일반전표입력',
      description: '일반 전표를 입력하고 관리합니다',
      icon: FileText,
      basePath: '/accounting/general-journal-entry',

      idField: 'id',

      actions: {
        getList: async () => ({
          success: true,
          data: journalData,
          totalCount: pagination.total,
        }),
      },

      columns: tableColumns,
      clientSideFiltering: false,
      itemsPerPage: 20,
      hideSearch: true,
      showCheckbox: false,

      // ===== 날짜 선택기 + 기간 버튼 + 검색 =====
      dateRangeSelector: {
        enabled: true,
        showPresets: false,
        startDate,
        endDate,
        onStartDateChange: setStartDate,
        onEndDateChange: setEndDate,
        extraActions: (
          <>
            <ScrollableButtonGroup>
              {PERIOD_BUTTONS.map((p) => (
                <Button
                  key={p.value}
                  size="sm"
                  variant={selectedPeriod === p.value ? 'default' : 'outline'}
                  className="h-8 px-3 text-xs shrink-0"
                  onClick={() => handlePeriodClick(p.value)}
                >
                  {p.label}
                </Button>
              ))}
            </ScrollableButtonGroup>

            <div className="relative">
              <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <Input
                placeholder="검색"
                value={searchKeyword}
                onChange={(e) => setSearchKeyword(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
                className="max-w-[200px] h-9 text-sm pl-8"
              />
            </div>

          </>
        ),
      },

      // ===== 통계 카드 5개 =====
      computeStats: (): StatCard[] => [
        { label: '전체', value: `${summary.totalCount}건`, icon: FileText, iconColor: 'text-gray-500' },
        { label: '입금', value: `${formatNumber(summary.depositAmount)}원`, icon: FileText, iconColor: 'text-blue-500' },
        { label: '출금', value: `${formatNumber(summary.withdrawalAmount)}원`, icon: FileText, iconColor: 'text-red-500' },
        { label: '분개완료', value: `${summary.journalCompleteCount}건`, icon: FileText, iconColor: 'text-green-500' },
        { label: '미분개', value: `${summary.journalIncompleteCount}건`, icon: FileText, iconColor: 'text-orange-500' },
      ],

      // ===== 헤더 액션 =====
      headerActions: () => (
        <div className="flex items-center gap-2">
          <Button variant="outline" size="sm" onClick={() => setShowAccountSetting(true)}>
            <Settings className="h-4 w-4 mr-1" />
            계정과목 설정
          </Button>
          <Button size="sm" onClick={() => setShowManualEntry(true)}>
            <PenLine className="h-4 w-4 mr-1" />
            수기 전표 입력
          </Button>
        </div>
      ),

      // ===== 테이블 행 렌더링 (기획서 기준 10컬럼) =====
      renderTableRow: (
        item: GeneralJournalRecord,
        _index: number,
        _globalIndex: number,
        _handlers: SelectionHandlers & RowClickHandlers<GeneralJournalRecord>
      ) => (
        <TableRow key={item.id} className="hover:bg-muted/50">
          <TableCell className="text-center text-sm w-[100px]">{item.date}</TableCell>
          <TableCell className="text-sm w-[140px]">
            <span className="flex items-center gap-1.5">
              <span className={`inline-block w-2 h-2 rounded-full flex-shrink-0 ${item.source === 'manual' ? 'bg-orange-400' : 'bg-blue-400'}`} />
              {item.description || '-'}
            </span>
          </TableCell>
          <TableCell className="text-right text-sm text-blue-600 w-[100px]">
            {item.depositAmount ? formatNumber(item.depositAmount) : '-'}
          </TableCell>
          <TableCell className="text-right text-sm text-red-600 w-[100px]">
            {item.withdrawalAmount ? formatNumber(item.withdrawalAmount) : '-'}
          </TableCell>
          <TableCell className="text-right text-sm w-[100px]">{formatNumber(item.balance)}</TableCell>
          <TableCell className="text-center text-sm w-[70px]">
            <Badge variant="outline" className="text-xs">
              {JOURNAL_DIVISION_LABELS[item.division] || item.division}
            </Badge>
          </TableCell>
          <TableCell className="text-sm w-[100px]">{item.journalDescription || '-'}</TableCell>
          <TableCell className="text-right text-sm w-[90px]">
            {item.debitAmount ? formatNumber(item.debitAmount) : '-'}
          </TableCell>
          <TableCell className="text-right text-sm w-[90px]">
            {item.creditAmount ? formatNumber(item.creditAmount) : '-'}
          </TableCell>
          <TableCell className="text-center w-[70px]">
            <Button
              variant="outline"
              size="sm"
              className="h-7 px-2 text-xs"
              onClick={(e) => {
                e.stopPropagation();
                setJournalEditTarget(item);
              }}
            >
              분개
            </Button>
          </TableCell>
        </TableRow>
      ),

      // ===== 모바일 카드 렌더링 =====
      renderMobileCard: (
        item: GeneralJournalRecord,
        _index: number,
        _globalIndex: number,
        _handlers: SelectionHandlers & RowClickHandlers<GeneralJournalRecord>
      ) => (
        <MobileCard
          key={item.id}
          title={item.description || '전표'}
          subtitle={item.date}
          badge={JOURNAL_DIVISION_LABELS[item.division] || item.division}
          badgeVariant="outline"
          onClick={() => setJournalEditTarget(item)}
          details={[
            { label: '입금', value: `${formatNumber(item.depositAmount || 0)}원` },
            { label: '출금', value: `${formatNumber(item.withdrawalAmount || 0)}원` },
            { label: '잔액', value: `${formatNumber(item.balance)}원` },
            { label: '차변', value: `${formatNumber(item.debitAmount || 0)}원` },
            { label: '대변', value: `${formatNumber(item.creditAmount || 0)}원` },
          ]}
        />
      ),

      // ===== 합계 행 + 범례 (테이블 안 tableFooter) =====
      tableFooter: (
        <>
          <TableRow className="bg-muted/50 font-medium">
            <TableCell colSpan={2} className="text-right font-bold">합계</TableCell>
            <TableCell className="text-right font-bold text-blue-600">
              {formatNumber(tableTotals.depositTotal)}
            </TableCell>
            <TableCell className="text-right font-bold text-red-600">
              {formatNumber(tableTotals.withdrawalTotal)}
            </TableCell>
            <TableCell />
            <TableCell />
            <TableCell />
            <TableCell className="text-right font-bold">
              {formatNumber(tableTotals.debitTotal)}
            </TableCell>
            <TableCell className="text-right font-bold">
              {formatNumber(tableTotals.creditTotal)}
            </TableCell>
            <TableCell />
          </TableRow>
          <TableRow>
            <TableCell colSpan={10} className="py-2">
              <div className="flex items-center gap-4 text-xs text-muted-foreground">
                <span className="flex items-center gap-1.5">
                  <span className="inline-block w-2.5 h-2.5 rounded-full bg-orange-400" />
                  수기 전표
                </span>
                <span className="flex items-center gap-1.5">
                  <span className="inline-block w-2.5 h-2.5 rounded-full bg-blue-400" />
                  연동 전표
                </span>
              </div>
            </TableCell>
          </TableRow>
        </>
      ),
    }),
    [
      journalData,
      pagination,
      summary,
      startDate,
      endDate,
      selectedPeriod,
      searchKeyword,
      tableTotals,
      handlePeriodClick,
      handleSearch,
    ]
  );

  return (
    <>
      <UniversalListPage
        config={config}
        initialData={journalData}
        externalPagination={{
          currentPage: pagination.currentPage,
          totalPages: pagination.lastPage,
          totalItems: pagination.total,
          itemsPerPage: pagination.perPage,
          onPageChange: setCurrentPage,
        }}
        externalIsLoading={isLoading}
      />

      {/* 계정과목 설정 팝업 */}
      <AccountSubjectSettingModal
        open={showAccountSetting}
        onOpenChange={setShowAccountSetting}
      />

      {/* 수기 전표 입력 팝업 */}
      <ManualJournalEntryModal
        open={showManualEntry}
        onOpenChange={setShowManualEntry}
        onSuccess={handleManualEntrySuccess}
      />

      {/* 분개 수정 팝업 */}
      {journalEditTarget && (
        <JournalEditModal
          open={!!journalEditTarget}
          onOpenChange={(open: boolean) => !open && setJournalEditTarget(null)}
          record={journalEditTarget}
          onSuccess={handleJournalEditSuccess}
        />
      )}
    </>
  );
}
