'use client';

import { useState, useCallback, useEffect, useRef } from 'react';
import { BookOpen, Printer, Search, Loader2, CreditCard } from 'lucide-react';
import { toast } from 'sonner';
import { PageHeader } from '@/components/organisms';
import { PageLayout } from '@/components/organisms';
import { Button } from '@/components/ui/button';
import { DateRangeSelector } from '@/components/molecules/DateRangeSelector';
import { Card } from '@/components/ui/card';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import { Badge } from '@/components/ui/badge';
import { AccountSubjectSelect } from '@/components/accounting/common';
import { getAccountSubjects } from '@/components/accounting/common/actions';
import type { AccountSubject } from '@/components/accounting/common/types';
import { getAccountLedger } from './actions';
import { JournalDetailModal } from './JournalDetailModal';
import type { AccountLedgerResponse, LedgerItem } from './types';
import { formatLedgerAmount, maskCardNumber } from './types';

function getDefaultStartDate(): string {
  const now = new Date();
  return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-01`;
}

function getDefaultEndDate(): string {
  const now = new Date();
  return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
}

function formatMonth(month: string): string {
  // "2026-01" → "2026년 01월"
  const [y, m] = month.split('-');
  return `${y}년 ${m}월`;
}

export function AccountLedger() {
  // 필터 상태
  const [startDate, setStartDate] = useState(getDefaultStartDate);
  const [endDate, setEndDate] = useState(getDefaultEndDate);
  const [accountCode, setAccountCode] = useState('');
  const subjectsRef = useRef<AccountSubject[]>([]);

  // 계정과목 목록 로드 (이름 조회용)
  useEffect(() => {
    getAccountSubjects({ depth: 3 }).then((res) => {
      if (res.success && res.data) subjectsRef.current = res.data;
    });
  }, []);

  // 데이터 상태
  const [data, setData] = useState<AccountLedgerResponse | null>(null);
  const [isLoading, setIsLoading] = useState(false);

  // 조회 시점 정보 (헤더 표시용)
  const [searchedInfo, setSearchedInfo] = useState<{
    code: string;
    name: string;
    startDate: string;
    endDate: string;
  } | null>(null);

  // 드릴다운 모달
  const [selectedItem, setSelectedItem] = useState<LedgerItem | null>(null);
  const [modalOpen, setModalOpen] = useState(false);

  const handleSearch = useCallback(async () => {
    if (!accountCode) {
      toast.error('계정과목을 선택해주세요.');
      return;
    }
    if (!startDate || !endDate) {
      toast.error('조회기간을 입력해주세요.');
      return;
    }

    setIsLoading(true);
    try {
      const result = await getAccountLedger({
        startDate,
        endDate,
        accountCode,
      });
      if (result.success && result.data) {
        setData(result.data);
        const subjectName = result.data.account?.name
          || subjectsRef.current.find((s) => s.code === accountCode)?.name
          || '';
        setSearchedInfo({
          code: result.data.account?.code || accountCode,
          name: subjectName,
          startDate,
          endDate,
        });
      } else {
        toast.error(result.error || '조회에 실패했습니다.');
        setData(null);
      }
    } catch {
      toast.error('조회 중 오류가 발생했습니다.');
      setData(null);
    } finally {
      setIsLoading(false);
    }
  }, [startDate, endDate, accountCode]);

  const handleRowClick = (item: LedgerItem) => {
    if (['journal', 'ecard_transaction', 'bank_transaction'].includes(item.source_type)) {
      setSelectedItem(item);
      setModalOpen(true);
    }
  };

  const handlePrint = () => {
    window.print();
  };

  const hasCarryForward = data && (
    data.carry_forward.debit !== 0 ||
    data.carry_forward.credit !== 0 ||
    data.carry_forward.balance !== 0
  );

  const hasTransactions = data && data.monthly_data.length > 0 &&
    data.monthly_data.some((m) => m.items.length > 0);

  return (
    <PageLayout>
      <div className="space-y-4">
        {/* 헤더 */}
        <PageHeader
          title="계정별원장"
          icon={BookOpen}
          actions={
            <Button
              variant="outline"
              size="sm"
              onClick={handlePrint}
              className="no-print"
              disabled={!data}
            >
              <Printer className="h-4 w-4 mr-1" />
              인쇄
            </Button>
          }
        />

        {/* 조회 필터 */}
        <Card className="p-3 md:p-4 no-print">
          <div className="flex flex-col gap-3">
            <DateRangeSelector
              startDate={startDate}
              endDate={endDate}
              onStartDateChange={setStartDate}
              onEndDateChange={setEndDate}
              hidePresets
              extraActions={
                <div className="flex items-center gap-2 w-full xl:flex-1 xl:min-w-0">
                  <div className="flex-1 min-w-0">
                    <AccountSubjectSelect
                      value={accountCode}
                      onValueChange={setAccountCode}
                    />
                  </div>
                  <Button onClick={handleSearch} disabled={isLoading} className="shrink-0">
                    {isLoading ? (
                      <Loader2 className="h-4 w-4 mr-1 animate-spin" />
                    ) : (
                      <Search className="h-4 w-4 mr-1" />
                    )}
                    조회
                  </Button>
                </div>
              }
            />
          </div>
        </Card>

        {/* 원장 테이블 */}
        {data && (
          <Card className="p-3 md:p-4">
            {/* 계정 정보 헤더 */}
            {searchedInfo && (
              <div className="mb-3">
                <span className="text-primary font-semibold">{searchedInfo.code}</span>
                {searchedInfo.name && (
                  <span className="font-semibold ml-2">{searchedInfo.name}</span>
                )}
                <span className="text-sm text-muted-foreground ml-3">
                  ({searchedInfo.startDate} ~ {searchedInfo.endDate})
                </span>
              </div>
            )}

            <div className="rounded-md border overflow-x-auto">
              <Table>
                <TableHeader className="bg-muted/50">
                  <TableRow>
                    <TableHead className="w-[90px]">날짜</TableHead>
                    <TableHead className="min-w-[200px]">적요</TableHead>
                    <TableHead className="min-w-[120px]">거래처</TableHead>
                    <TableHead className="w-[110px]">사업자번호</TableHead>
                    <TableHead className="w-[110px] text-right">차변</TableHead>
                    <TableHead className="w-[110px] text-right">대변</TableHead>
                    <TableHead className="w-[120px] text-right">잔액</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {/* 거래 내역이 없을 때 */}
                  {!hasTransactions && (
                    <TableRow>
                      <TableCell colSpan={7} className="h-32 text-center text-muted-foreground">
                        조회 기간 내 거래 내역이 없습니다.
                      </TableCell>
                    </TableRow>
                  )}

                  {/* 거래 내역이 있을 때 */}
                  {hasTransactions && (
                    <>
                      {/* 이월잔액 */}
                      <TableRow className={hasCarryForward ? 'bg-yellow-50 font-semibold' : 'bg-yellow-50/50'}>
                        <TableCell>-</TableCell>
                        <TableCell className={hasCarryForward ? '' : 'text-muted-foreground'}>
                          이월잔액
                        </TableCell>
                        <TableCell />
                        <TableCell />
                        <TableCell className="text-right">
                          {formatLedgerAmount(data.carry_forward.debit)}
                        </TableCell>
                        <TableCell className="text-right">
                          {formatLedgerAmount(data.carry_forward.credit)}
                        </TableCell>
                        <TableCell className="text-right">
                          {formatLedgerAmount(data.carry_forward.balance) || '0'}
                        </TableCell>
                      </TableRow>

                      {/* 월별 데이터 */}
                      {data.monthly_data.map((month) => (
                        <MonthBlock
                          key={month.month}
                          month={month}
                          onRowClick={handleRowClick}
                        />
                      ))}

                      {/* 총합계 */}
                      <TableRow className="bg-indigo-50 font-semibold">
                        <TableCell />
                        <TableCell>총 합 계</TableCell>
                        <TableCell />
                        <TableCell />
                        <TableCell className="text-right">
                          {formatLedgerAmount(data.grand_total.debit)}
                        </TableCell>
                        <TableCell className="text-right">
                          {formatLedgerAmount(data.grand_total.credit)}
                        </TableCell>
                        <TableCell className="text-right">
                          {formatLedgerAmount(data.grand_total.balance)}
                        </TableCell>
                      </TableRow>
                    </>
                  )}
                </TableBody>
              </Table>
            </div>
          </Card>
        )}

        {/* 빈 상태 */}
        {!data && !isLoading && (
          <Card className="p-12 text-center text-muted-foreground">
            <BookOpen className="h-12 w-12 mx-auto mb-3 opacity-30" />
            <p>계정과목을 선택하고 조회 버튼을 클릭하세요.</p>
          </Card>
        )}

        {/* 로딩 */}
        {isLoading && (
          <Card className="p-12 text-center text-muted-foreground">
            <Loader2 className="h-8 w-8 mx-auto mb-3 animate-spin" />
            <p>조회 중...</p>
          </Card>
        )}
      </div>

      {/* 전표 상세 모달 */}
      <JournalDetailModal
        open={modalOpen}
        onOpenChange={setModalOpen}
        item={selectedItem}
      />
    </PageLayout>
  );
}

// ===== 월별 블록 서브 컴포넌트 =====
function MonthBlock({
  month,
  onRowClick,
}: {
  month: AccountLedgerResponse['monthly_data'][number];
  onRowClick: (item: LedgerItem) => void;
}) {
  return (
    <>
      {/* 거래 행 */}
      {month.items.map((item, idx) => (
        <TableRow
          key={`${month.month}-${idx}`}
          className={
            item.source_type !== 'none'
              ? 'cursor-pointer hover:bg-muted/50 transition-colors'
              : ''
          }
          onClick={() => onRowClick(item)}
        >
          <TableCell className="text-sm whitespace-nowrap">
            {item.date.slice(5)} {/* MM-DD */}
          </TableCell>
          <TableCell>
            {item.card_tx ? (
              <div>
                <div className="flex items-center gap-1.5">
                  <CreditCard className="h-3.5 w-3.5 text-blue-500 shrink-0" />
                  <span className="text-sm">{item.description || '-'}</span>
                  <DeductionBadge type={item.card_tx.deduction_type} />
                </div>
                <div className="text-xs text-muted-foreground mt-0.5">
                  {item.card_tx.card_company_name} {maskCardNumber(item.card_tx.card_num)}
                </div>
              </div>
            ) : (
              <span className="text-sm">{item.description || '-'}</span>
            )}
          </TableCell>
          <TableCell className="text-sm">
            {item.card_tx?.merchant_name || item.trading_partner_name || ''}
          </TableCell>
          <TableCell className="text-sm font-mono">
            {item.card_tx?.merchant_biz_num || item.biz_no || ''}
          </TableCell>
          <TableCell className="text-right text-sm tabular-nums">
            {formatLedgerAmount(item.debit_amount)}
          </TableCell>
          <TableCell className="text-right text-sm tabular-nums">
            {formatLedgerAmount(item.credit_amount)}
          </TableCell>
          <TableCell className="text-right text-sm tabular-nums font-medium">
            {formatLedgerAmount(item.balance)}
          </TableCell>
        </TableRow>
      ))}

      {/* 월 소계 */}
      <TableRow className="bg-gray-50 font-semibold">
        <TableCell />
        <TableCell className="text-sm">{formatMonth(month.month)} 계</TableCell>
        <TableCell />
        <TableCell />
        <TableCell className="text-right text-sm tabular-nums">
          {formatLedgerAmount(month.subtotal.debit)}
        </TableCell>
        <TableCell className="text-right text-sm tabular-nums">
          {formatLedgerAmount(month.subtotal.credit)}
        </TableCell>
        <TableCell />
      </TableRow>

      {/* 누계 */}
      <TableRow className="bg-gray-50 font-semibold">
        <TableCell />
        <TableCell className="text-sm pl-6">누 계</TableCell>
        <TableCell />
        <TableCell />
        <TableCell className="text-right text-sm tabular-nums">
          {formatLedgerAmount(month.cumulative.debit)}
        </TableCell>
        <TableCell className="text-right text-sm tabular-nums">
          {formatLedgerAmount(month.cumulative.credit)}
        </TableCell>
        <TableCell />
      </TableRow>
    </>
  );
}

// ===== 공제/불공제 배지 =====
function DeductionBadge({ type }: { type: string }) {
  if (type === 'deductible') {
    return (
      <Badge variant="outline" className="text-[10px] px-1.5 py-0 h-4 bg-green-50 text-green-700 border-green-200">
        공제
      </Badge>
    );
  }
  if (type === 'non_deductible') {
    return (
      <Badge variant="outline" className="text-[10px] px-1.5 py-0 h-4 bg-red-50 text-red-700 border-red-200">
        불공제
      </Badge>
    );
  }
  return null;
}
