'use client';

/**
 * 세금계산서 관리 - 메인 리스트 페이지
 *
 * - 매출/매입 탭 (카운트 표시)
 * - 일자유형 Select + 날짜범위 + 분기버튼 + 거래처 검색
 * - 요약 카드 (매출/매입 공급가액/세액/합계)
 * - 테이블 + 범례 + 기간 요약
 * - 분개 버튼 → JournalEntryModal
 * - 수기 입력 버튼 → ManualEntryModal
 */

import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
import dynamic from 'next/dynamic';
import { toast } from 'sonner';
import {
  FileText,
  Download,
  PenLine,
  Search,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent } from '@/components/ui/card';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { StatCards } from '@/components/organisms/StatCards';
import { DateRangeSelector } from '@/components/molecules/DateRangeSelector';
import { TableRow, TableCell } from '@/components/ui/table';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  UniversalListPage,
  type UniversalListConfig,
  type SelectionHandlers,
  type RowClickHandlers,
} from '@/components/templates/UniversalListPage';
import { MobileCard } from '@/components/organisms/MobileCard';
import {
  getTaxInvoices,
  getTaxInvoiceSummary,
} from './actions';
import { downloadExcel, type ExcelColumn } from '@/lib/utils/excel-download';

const ManualEntryModal = dynamic(
  () => import('./ManualEntryModal').then(mod => ({ default: mod.ManualEntryModal })),
);
const JournalEntryModal = dynamic(
  () => import('./JournalEntryModal').then(mod => ({ default: mod.JournalEntryModal })),
);
import type {
  TaxInvoiceMgmtRecord,
  InvoiceTab,
  TaxInvoiceSummary,
  TaxType,
  ReceiptType,
  InvoiceStatus,
  InvoiceSource,
} from './types';
import {
  TAB_OPTIONS,
  DATE_TYPE_OPTIONS,
  TAX_TYPE_LABELS,
  RECEIPT_TYPE_LABELS,
  INVOICE_STATUS_MAP,
  INVOICE_SOURCE_LABELS,
} from './types';
import { formatNumber } from '@/lib/utils/amount';

// ===== 분기 옵션 =====
const QUARTER_BUTTONS = [
  { value: 'Q1', label: '1분기', startMonth: 1, endMonth: 3 },
  { value: 'Q2', label: '2분기', startMonth: 4, endMonth: 6 },
  { value: 'Q3', label: '3분기', startMonth: 7, endMonth: 9 },
  { value: 'Q4', label: '4분기', startMonth: 10, endMonth: 12 },
];

// ===== 엑셀 다운로드 컬럼 =====
const excelColumns: ExcelColumn<TaxInvoiceMgmtRecord & Record<string, unknown>>[] = [
  { header: '작성일자', key: 'writeDate', width: 12 },
  { header: '발급일자', key: 'issueDate', width: 12 },
  { header: '거래처', key: 'vendorName', width: 20 },
  { header: '사업자번호', key: 'vendorBusinessNumber', width: 15 },
  { header: '과세형태', key: 'taxType', width: 10,
    transform: (v) => TAX_TYPE_LABELS[v as TaxType] || String(v || '') },
  { header: '품목', key: 'itemName', width: 15 },
  { header: '공급가액', key: 'supplyAmount', width: 14 },
  { header: '세액', key: 'taxAmount', width: 14 },
  { header: '합계', key: 'totalAmount', width: 14 },
  { header: '영수청구', key: 'receiptType', width: 10,
    transform: (v) => RECEIPT_TYPE_LABELS[v as ReceiptType] || String(v || '') },
  { header: '상태', key: 'status', width: 10,
    transform: (v) => INVOICE_STATUS_MAP[v as InvoiceStatus]?.label || String(v || '') },
  { header: '발급형태', key: 'source', width: 10,
    transform: (v) => INVOICE_SOURCE_LABELS[v as InvoiceSource] || String(v || '') },
];

// ===== 테이블 컬럼 =====
const tableColumns = [
  { key: 'writeDate', label: '작성일자', className: 'text-center', sortable: true, copyable: true },
  { key: 'issueDate', label: '발급일자', className: 'text-center', sortable: true, copyable: true },
  { key: 'vendorName', label: '거래처', sortable: true, copyable: true },
  { key: 'vendorBusinessNumber', label: '사업자번호\n(주민번호)', className: 'text-center', sortable: true, copyable: true },
  { key: 'taxType', label: '과세형태', className: 'text-center', sortable: true, copyable: true },
  { key: 'itemName', label: '품목', sortable: true, copyable: true },
  { key: 'supplyAmount', label: '공급가액', className: 'text-right', sortable: true, copyable: true },
  { key: 'taxAmount', label: '세액', className: 'text-right', sortable: true, copyable: true },
  { key: 'totalAmount', label: '합계', className: 'text-right', sortable: true, copyable: true },
  { key: 'receiptType', label: '영수청구', className: 'text-center', sortable: true, copyable: true },
  { key: 'documentType', label: '문서형태', className: 'text-center', sortable: true, copyable: true },
  { key: 'issueType', label: '발급형태', className: 'text-center', sortable: true, copyable: true },
  { key: 'status', label: '상태', className: 'text-center', sortable: true },
  { key: 'journal', label: '분개', className: 'text-center w-[80px]' },
];

// ===== 날짜 헬퍼 =====
function getQuarterDates(year: number, quarter: string) {
  const q = QUARTER_BUTTONS.find((b) => b.value === quarter);
  if (!q) return { start: '', end: '' };
  const start = `${year}-${String(q.startMonth).padStart(2, '0')}-01`;
  const lastDay = new Date(year, q.endMonth, 0).getDate();
  const end = `${year}-${String(q.endMonth).padStart(2, '0')}-${String(lastDay).padStart(2, '0')}`;
  return { start, end };
}

function getCurrentQuarter(): string {
  const month = new Date().getMonth() + 1;
  if (month <= 3) return 'Q1';
  if (month <= 6) return 'Q2';
  if (month <= 9) return 'Q3';
  return 'Q4';
}

export function TaxInvoiceManagement() {
  // ===== 필터 상태 =====
  const currentYear = new Date().getFullYear();
  const [activeTab, setActiveTab] = useState<InvoiceTab>('sales');
  const [dateType, setDateType] = useState('write_date');
  const [selectedQuarter, setSelectedQuarter] = useState(getCurrentQuarter());
  const [startDate, setStartDate] = useState(() => {
    const q = getQuarterDates(currentYear, getCurrentQuarter());
    return q.start;
  });
  const [endDate, setEndDate] = useState(() => {
    const q = getQuarterDates(currentYear, getCurrentQuarter());
    return q.end;
  });
  const [vendorSearch, setVendorSearch] = useState('');

  // ===== 데이터 상태 =====
  const [invoiceData, setInvoiceData] = useState<TaxInvoiceMgmtRecord[]>([]);
  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<TaxInvoiceSummary>({
    salesSupplyAmount: 0,
    salesTaxAmount: 0,
    salesTotalAmount: 0,
    salesCount: 0,
    purchaseSupplyAmount: 0,
    purchaseTaxAmount: 0,
    purchaseTotalAmount: 0,
    purchaseCount: 0,
  });

  // ===== 모달 상태 =====
  const [showManualEntry, setShowManualEntry] = useState(false);
  const [journalTarget, setJournalTarget] = useState<TaxInvoiceMgmtRecord | null>(null);

  // ===== 분기 버튼 클릭 =====
  const handleQuarterClick = useCallback((quarter: string) => {
    setSelectedQuarter(quarter);
    const dates = getQuarterDates(currentYear, quarter);
    setStartDate(dates.start);
    setEndDate(dates.end);
    setCurrentPage(1);
  }, [currentYear]);

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

      if (listResult.success) {
        setInvoiceData(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;
    }
  }, [activeTab, dateType, startDate, endDate, vendorSearch, currentPage]);

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

  // ===== 탭 변경 =====
  const handleTabChange = useCallback((tab: InvoiceTab) => {
    setActiveTab(tab);
    setCurrentPage(1);
  }, []);

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

  // ===== 엑셀 다운로드 (프론트 xlsx 생성) =====
  const handleExcelDownload = useCallback(async () => {
    try {
      toast.info('엑셀 파일 생성 중...');
      const allData: TaxInvoiceMgmtRecord[] = [];
      let page = 1;
      let lastPage = 1;

      do {
        const result = await getTaxInvoices({
          division: activeTab,
          dateType,
          startDate,
          endDate,
          vendorSearch,
          page,
          perPage: 100,
        });
        if (result.success && result.data.length > 0) {
          allData.push(...result.data);
          lastPage = result.pagination?.lastPage ?? 1;
        } else {
          break;
        }
        page++;
      } while (page <= lastPage);

      if (allData.length > 0) {
        await downloadExcel({
          data: allData as (TaxInvoiceMgmtRecord & Record<string, unknown>)[],
          columns: excelColumns,
          filename: `세금계산서_${activeTab === 'sales' ? '매출' : '매입'}`,
          sheetName: activeTab === 'sales' ? '매출' : '매입',
        });
        toast.success('엑셀 다운로드 완료');
      } else {
        toast.warning('다운로드할 데이터가 없습니다.');
      }
    } catch {
      toast.error('엑셀 다운로드에 실패했습니다.');
    }
  }, [activeTab, dateType, startDate, endDate, vendorSearch]);

  // ===== 수기 등록 완료 =====
  const handleManualEntrySuccess = useCallback(() => {
    setShowManualEntry(false);
    loadData();
    toast.success('세금계산서가 등록되었습니다.');
  }, [loadData]);

  // ===== 분개 완료 =====
  const handleJournalSuccess = useCallback(() => {
    setJournalTarget(null);
    loadData();
  }, [loadData]);

  // ===== 기간 요약 계산 =====
  const periodDifference = useMemo(() => {
    return summary.salesTotalAmount - summary.purchaseTotalAmount;
  }, [summary]);

  // ===== UniversalListPage Config =====
  const config: UniversalListConfig<TaxInvoiceMgmtRecord> = useMemo(
    () => ({
      title: '세금계산서 관리',
      description: '홈택스에 신고된 세금계산서 매입/매출 내역을 조회하고 관리합니다',
      icon: FileText,
      basePath: '/accounting/tax-invoices',

      idField: 'id',

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

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

      // ===== 검색 영역 (beforeTableContent) =====
      beforeTableContent: (
        <div className="space-y-3">
          {/* 검색 필터 카드 */}
          <Card>
            <CardContent className="p-4 space-y-3">
              {/* Row1: 일자타입 + 날짜범위 + 분기 버튼 + 조회 */}
              <div className="flex flex-col lg:flex-row lg:items-center gap-2">
                <Select value={dateType} onValueChange={setDateType}>
                  <SelectTrigger className="w-full lg:min-w-[120px] lg:w-auto h-9 text-sm">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {DATE_TYPE_OPTIONS.map((opt) => (
                      <SelectItem key={opt.value} value={opt.value}>
                        {opt.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>

                <DateRangeSelector
                  startDate={startDate}
                  endDate={endDate}
                  onStartDateChange={setStartDate}
                  onEndDateChange={setEndDate}
                  hidePresets
                />

                <div className="flex gap-1">
                  {QUARTER_BUTTONS.map((q) => (
                    <Button
                      key={q.value}
                      size="sm"
                      variant={selectedQuarter === q.value ? 'default' : 'outline'}
                      onClick={() => handleQuarterClick(q.value)}
                    >
                      {q.label}
                    </Button>
                  ))}
                </div>

                <Button size="sm" onClick={handleSearch}>
                  조회
                </Button>
              </div>

              {/* Row2: 거래처 검색 (아이콘 포함) */}
              <div className="relative max-w-md">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
                <Input
                  value={vendorSearch}
                  onChange={(e) => setVendorSearch(e.target.value)}
                  onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
                  placeholder="사업자 번호 또는 사업자명"
                  className="pl-9 h-9"
                />
              </div>
            </CardContent>
          </Card>

          {/* 요약 카드 5개 */}
          <StatCards
            stats={[
              { label: '매출 공급가액', value: `${formatNumber(summary.salesSupplyAmount)}원` },
              { label: '매출 세액', value: `${formatNumber(summary.salesTaxAmount)}원` },
              { label: '매입 과세 공급가액', value: `${formatNumber(summary.purchaseSupplyAmount)}원` },
              { label: '매입 면세 공급가액', value: '0원' },
              { label: '매입 세액', value: `${formatNumber(summary.purchaseTaxAmount)}원` },
            ]}
          />

          {/* 매출/매입 탭 + 액션 버튼 */}
          <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
            <Tabs value={activeTab} onValueChange={(v) => handleTabChange(v as InvoiceTab)}>
              <TabsList>
                {TAB_OPTIONS.map((t) => (
                  <TabsTrigger key={t.value} value={t.value}>
                    {t.label} {t.value === 'sales' ? summary.salesCount : summary.purchaseCount}
                  </TabsTrigger>
                ))}
              </TabsList>
            </Tabs>
            <div className="flex items-center gap-2">
              <Button variant="outline" size="sm" onClick={handleExcelDownload}>
                <Download className="h-4 w-4 mr-1" />
                엑셀 다운로드
              </Button>
              <Button size="sm" onClick={() => setShowManualEntry(true)}>
                <PenLine className="h-4 w-4 mr-1" />
                수기 입력
              </Button>
            </div>
          </div>
        </div>
      ),

      // 탭은 beforeTableContent에서 수동 렌더링 (카드와 테이블 사이)

      // ===== 테이블 행 렌더링 =====
      renderTableRow: (
        item: TaxInvoiceMgmtRecord,
        _index: number,
        _globalIndex: number,
        _handlers: SelectionHandlers & RowClickHandlers<TaxInvoiceMgmtRecord>
      ) => (
        <TableRow
          key={item.id}
          className={`hover:bg-muted/50 ${item.source === 'manual' ? 'bg-yellow-50/50' : ''}`}
        >
          <TableCell className="text-center text-sm">{item.writeDate}</TableCell>
          <TableCell className="text-center text-sm">{item.issueDate || '-'}</TableCell>
          <TableCell className="text-sm">{item.vendorName}</TableCell>
          <TableCell className="text-center text-sm">{item.vendorBusinessNumber}</TableCell>
          <TableCell className="text-center">
            <Badge variant="outline" className="text-xs">
              {TAX_TYPE_LABELS[item.taxType]}
            </Badge>
          </TableCell>
          <TableCell className="text-sm">{item.itemName || '-'}</TableCell>
          <TableCell className="text-right text-sm">{formatNumber(item.supplyAmount)}</TableCell>
          <TableCell className="text-right text-sm">{formatNumber(item.taxAmount)}</TableCell>
          <TableCell className="text-right text-sm font-medium">{formatNumber(item.totalAmount)}</TableCell>
          <TableCell className="text-center text-sm">
            <span className="inline-flex items-center gap-1">
              <span className={`inline-block w-2 h-2 rounded-full ${item.source === 'manual' ? 'bg-purple-500' : 'bg-blue-500'}`} />
              {RECEIPT_TYPE_LABELS[item.receiptType]}
            </span>
          </TableCell>
          <TableCell className="text-center text-sm">{item.documentNumber || '-'}</TableCell>
          <TableCell className="text-center text-sm">{INVOICE_SOURCE_LABELS[item.source]}</TableCell>
          <TableCell className="text-center">
            <Badge className={`text-xs ${INVOICE_STATUS_MAP[item.status].color}`}>
              {INVOICE_STATUS_MAP[item.status].label}
            </Badge>
          </TableCell>
          <TableCell className="text-center">
            <Button
              variant="outline"
              size="sm"
              className="h-7 px-2 text-xs"
              onClick={(e) => {
                e.stopPropagation();
                setJournalTarget(item);
              }}
            >
              분개
            </Button>
          </TableCell>
        </TableRow>
      ),

      // ===== 모바일 카드 렌더링 =====
      renderMobileCard: (
        item: TaxInvoiceMgmtRecord,
        _index: number,
        _globalIndex: number,
        _handlers: SelectionHandlers & RowClickHandlers<TaxInvoiceMgmtRecord>
      ) => (
        <MobileCard
          key={item.id}
          title={item.vendorName}
          subtitle={item.documentNumber || item.writeDate}
          badge={INVOICE_STATUS_MAP[item.status].label}
          badgeVariant="outline"
          onClick={() => setJournalTarget(item)}
          details={[
            { label: '작성일자', value: item.writeDate },
            { label: '공급가액', value: `${formatNumber(item.supplyAmount)}원` },
            { label: '세액', value: `${formatNumber(item.taxAmount)}원` },
            { label: '합계', value: `${formatNumber(item.totalAmount)}원` },
            { label: '과세여부', value: TAX_TYPE_LABELS[item.taxType] },
            { label: '소스', value: INVOICE_SOURCE_LABELS[item.source] },
          ]}
        />
      ),

      // ===== 범례 (테이블 안) =====
      tableFooter: (
        <TableRow>
          <TableCell colSpan={14} className="py-2">
            <div className="flex items-center gap-4 text-xs text-muted-foreground">
              <div className="flex items-center gap-1.5">
                <div className="w-2.5 h-2.5 bg-purple-500 rounded-full" />
                <span>수기 세금계산서</span>
              </div>
              <div className="flex items-center gap-1.5">
                <div className="w-2.5 h-2.5 bg-blue-500 rounded-full" />
                <span>홈택스 연동 세금계산서</span>
              </div>
            </div>
          </TableCell>
        </TableRow>
      ),

      // ===== 기간 요약 (테이블 뒤) =====
      afterTableContent: () => (
        <Card>
          <CardContent className="p-4">
            <div className="text-sm font-semibold mb-3">기간 요약</div>
            {/* 모바일: 세로 스택, sm 이상: 가로 배치 */}
            <div className="flex flex-col sm:flex-row items-center justify-center gap-2 sm:gap-4 text-center">
              <div className="w-full sm:w-auto">
                <div className="text-xs text-muted-foreground mb-1">매출 합계 (공급가액 + 세액)</div>
                <div className="text-lg sm:text-xl font-bold">{formatNumber(summary.salesTotalAmount)}원</div>
              </div>
              <div className="text-xl sm:text-2xl font-bold text-muted-foreground">⊖</div>
              <div className="w-full sm:w-auto">
                <div className="text-xs text-muted-foreground mb-1">매입 합계 (공급가액 + 세액)</div>
                <div className="text-lg sm:text-xl font-bold">{formatNumber(summary.purchaseTotalAmount)}원</div>
              </div>
              <div className="text-xl sm:text-2xl font-bold text-muted-foreground">=</div>
              <div className="w-full sm:w-auto">
                <div className="text-xs text-muted-foreground mb-1">예상 부가세</div>
                <div className={`text-lg sm:text-xl font-bold ${periodDifference >= 0 ? 'text-blue-700' : 'text-red-700'}`}>
                  {formatNumber(periodDifference)}원
                </div>
              </div>
            </div>
          </CardContent>
        </Card>
      ),
    }),
    [
      invoiceData,
      pagination,
      summary,
      dateType,
      startDate,
      endDate,
      selectedQuarter,
      vendorSearch,
      periodDifference,
      handleQuarterClick,
      handleSearch,
      handleExcelDownload,
    ]
  );

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

      {/* 수기 입력 팝업 */}
      <ManualEntryModal
        open={showManualEntry}
        onOpenChange={setShowManualEntry}
        onSuccess={handleManualEntrySuccess}
        defaultDivision={activeTab}
      />

      {/* 분개 수정 팝업 */}
      {journalTarget && (
        <JournalEntryModal
          open={!!journalTarget}
          onOpenChange={(open: boolean) => !open && setJournalTarget(null)}
          invoice={journalTarget}
          onSuccess={handleJournalSuccess}
        />
      )}
    </>
  );
}
