'use client';

/**
 * 거래처원장 - UniversalListPage 마이그레이션
 *
 * 기존 IntegratedListTemplateV2 → UniversalListPage config 기반으로 변환
 * - 서버 사이드 필터링/페이지네이션
 * - dateRangeSelector + 엑셀 다운로드 버튼 (headerActions)
 * - tableFooter: 합계 행
 * - Stats 카드 (API 통계)
 */

import { useState, useMemo, useCallback, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { format, startOfMonth, endOfMonth } from 'date-fns';
import { Download, FileText } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { TableRow, TableCell } from '@/components/ui/table';
import { MobileCard } from '@/components/organisms/MobileCard';
import {
  UniversalListPage,
  type UniversalListConfig,
  type SelectionHandlers,
  type RowClickHandlers,
  type StatCard,
} from '@/components/templates/UniversalListPage';
import type { VendorLedgerItem, VendorLedgerSummary } from './types';
import { getVendorLedgerList, getVendorLedgerSummary } from './actions';
import { formatNumber } from '@/lib/utils/amount';
import { downloadExcel, type ExcelColumn } from '@/lib/utils/excel-download';
import { toast } from 'sonner';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { usePermission } from '@/hooks/usePermission';

// ===== 테이블 컬럼 정의 =====
const tableColumns = [
  { key: 'no', label: 'No.', className: 'text-center w-[60px]' },
  { key: 'vendorName', label: '거래처명', sortable: true, copyable: true },
  { key: 'carryoverBalance', label: '이월잔액', className: 'text-right w-[120px]', sortable: true, copyable: true },
  { key: 'sales', label: '매출', className: 'text-right w-[120px]', sortable: true, copyable: true },
  { key: 'collection', label: '수금', className: 'text-right w-[120px]', sortable: true, copyable: true },
  { key: 'balance', label: '잔액', className: 'text-right w-[120px]', sortable: true, copyable: true },
  { key: 'paymentDate', label: '결제일', className: 'text-center w-[100px]', sortable: true, copyable: true },
];

// ===== 엑셀 컬럼 정의 =====
const excelColumns: ExcelColumn<VendorLedgerItem & Record<string, unknown>>[] = [
  { header: '거래처명', key: 'vendorName', width: 20 },
  { header: '이월잔액', key: 'carryoverBalance', width: 14 },
  { header: '매출', key: 'sales', width: 14 },
  { header: '수금', key: 'collection', width: 14 },
  { header: '잔액', key: 'balance', width: 14 },
  { header: '결제일', key: 'paymentDate', width: 12 },
];

// ===== Props =====
interface VendorLedgerProps {
  initialData?: VendorLedgerItem[];
  initialSummary?: VendorLedgerSummary;
  initialPagination?: {
    currentPage: number;
    lastPage: number;
    perPage: number;
    total: number;
  };
}

export function VendorLedger({
  initialData = [],
  initialSummary,
  initialPagination,
}: VendorLedgerProps) {
  const router = useRouter();
  const { canExport } = usePermission();

  // ===== 외부 상태 (UniversalListPage 외부에서 관리) =====
  const [data, setData] = useState<VendorLedgerItem[]>(initialData);
  const [summary, setSummary] = useState<VendorLedgerSummary>(
    initialSummary || { carryoverBalance: 0, totalSales: 0, totalCollection: 0, balance: 0 }
  );
  const [pagination, setPagination] = useState(
    initialPagination || { currentPage: 1, lastPage: 1, perPage: 20, total: 0 }
  );

  // 필터 상태
  const [searchQuery, setSearchQuery] = useState('');
  const [startDate, setStartDate] = useState(() => format(startOfMonth(new Date()), 'yyyy-MM-dd'));
  const [endDate, setEndDate] = useState(() => format(endOfMonth(new Date()), 'yyyy-MM-dd'));
  const [currentPage, setCurrentPage] = useState(initialPagination?.currentPage || 1);
  const [isLoading, setIsLoading] = useState(false);

  // ===== 데이터 로드 =====
  const loadData = useCallback(async () => {
    setIsLoading(true);
    try {
      const [listResult, summaryResult] = await Promise.all([
        getVendorLedgerList({
          page: currentPage,
          perPage: 20,
          startDate,
          endDate,
          search: searchQuery || undefined,
        }),
        getVendorLedgerSummary({
          startDate,
          endDate,
        }),
      ]);

      if (listResult.success) {
        setData(listResult.data);
        setPagination(listResult.pagination);
      }

      if (summaryResult.success && summaryResult.data) {
        setSummary(summaryResult.data);
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('[VendorLedger] loadData error:', error);
    } finally {
      setIsLoading(false);
    }
  }, [currentPage, startDate, endDate, searchQuery]);

  // 필터 변경 시 데이터 재로드
  useEffect(() => {
    loadData();
  }, [loadData]);

  // ===== 합계 계산 =====
  const totals = useMemo(() => {
    return data.reduce(
      (acc, item) => ({
        carryoverBalance: acc.carryoverBalance + item.carryoverBalance,
        sales: acc.sales + item.sales,
        collection: acc.collection + item.collection,
        balance: acc.balance + item.balance,
      }),
      { carryoverBalance: 0, sales: 0, collection: 0, balance: 0 }
    );
  }, [data]);

  // ===== 핸들러 =====
  const handleRowClick = useCallback(
    (item: VendorLedgerItem) => {
      const params = new URLSearchParams();
      if (startDate) params.set('start_date', startDate);
      if (endDate) params.set('end_date', endDate);
      const queryString = params.toString();
      router.push(`/ko/accounting/vendor-ledger/${item.id}?mode=view${queryString ? `&${queryString}` : ''}`);
    },
    [router, startDate, endDate]
  );

  const handleExcelDownload = useCallback(async () => {
    try {
      toast.info('엑셀 파일 생성 중...');
      const allData: VendorLedgerItem[] = [];
      let page = 1;
      let lastPage = 1;

      do {
        const result = await getVendorLedgerList({
          startDate,
          endDate,
          search: searchQuery || undefined,
          perPage: 100,
          page,
        });
        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<VendorLedgerItem & Record<string, unknown>>({
          data: allData as (VendorLedgerItem & Record<string, unknown>)[],
          columns: excelColumns,
          filename: '거래처원장',
          sheetName: '거래처원장',
        });
        toast.success('엑셀 다운로드 완료');
      } else {
        toast.warning('다운로드할 데이터가 없습니다.');
      }
    } catch {
      toast.error('엑셀 다운로드에 실패했습니다.');
    }
  }, [startDate, endDate, searchQuery]);

  // ===== 금액 포맷 =====
  const formatAmount = (amount: number) => {
    if (amount === 0) return '';
    return formatNumber(amount);
  };

  // ===== UniversalListPage Config =====
  const config: UniversalListConfig<VendorLedgerItem> = useMemo(
    () => ({
      // 페이지 기본 정보
      title: '거래처원장',
      description: '거래처별 기간 내역을 조회합니다.',
      icon: FileText,
      basePath: '/accounting/vendor-ledger',

      // ID 추출
      idField: 'id',

      // API 액션
      actions: {
        getList: async () => {
          return {
            success: true,
            data: data,
            totalCount: pagination.total,
          };
        },
      },

      // 테이블 컬럼
      columns: tableColumns,

      // 서버 사이드 필터링
      clientSideFiltering: false,
      itemsPerPage: 20,
      isLoading,

      // 검색
      searchPlaceholder: '거래처명 검색...',
      onSearchChange: setSearchQuery,
      searchFilter: (item: VendorLedgerItem, search: string) => {
        const s = search.toLowerCase();
        return (
          item.vendorName?.toLowerCase().includes(s) ||
          false
        );
      },

      // 날짜 선택기
      dateRangeSelector: {
        enabled: true,
        startDate,
        endDate,
        onStartDateChange: setStartDate,
        onEndDateChange: setEndDate,
      },

      // 헤더 액션 (엑셀 다운로드) - 함수로 변환
      headerActions: () => (
        canExport ? (
          <Button variant="outline" size="sm" onClick={handleExcelDownload}>
            <Download className="mr-2 h-4 w-4" />
            엑셀 다운로드
          </Button>
        ) : null
      ),

      // 테이블 푸터 (합계 행)
      tableFooter: (
        <TableRow className="bg-gray-100 font-medium">
          <TableCell className="text-center" />
          <TableCell className="text-center font-bold">합계</TableCell>
          <TableCell />
          <TableCell className="text-right">{formatAmount(totals.carryoverBalance)}</TableCell>
          <TableCell className="text-right">{formatAmount(totals.sales)}</TableCell>
          <TableCell className="text-right">{formatAmount(totals.collection)}</TableCell>
          <TableCell className="text-right">{formatAmount(totals.balance)}</TableCell>
          <TableCell />
        </TableRow>
      ),

      // Stats 카드
      computeStats: (): StatCard[] => [
        {
          label: '전기 이월',
          value: `${formatNumber(summary.carryoverBalance)}원`,
          icon: FileText,
          iconColor: 'text-blue-500',
        },
        {
          label: '매출',
          value: `${formatNumber(summary.totalSales)}원`,
          icon: FileText,
          iconColor: 'text-green-500',
        },
        {
          label: '수금',
          value: `${formatNumber(summary.totalCollection)}원`,
          icon: FileText,
          iconColor: 'text-orange-500',
        },
        {
          label: '잔액',
          value: `${formatNumber(summary.balance)}원`,
          icon: FileText,
          iconColor: 'text-red-500',
        },
      ],

      // 테이블 행 렌더링
      renderTableRow: (
        item: VendorLedgerItem,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<VendorLedgerItem>
      ) => (
        <TableRow
          key={item.id}
          className="hover:bg-muted/50 cursor-pointer"
          onClick={() => handleRowClick(item)}
        >
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            <Checkbox checked={handlers.isSelected} onCheckedChange={handlers.onToggle} />
          </TableCell>
          {/* No. */}
          <TableCell className="text-center text-sm text-gray-500">{globalIndex}</TableCell>
          {/* 거래처명 */}
          <TableCell className="font-medium">{item.vendorName}</TableCell>
          {/* 이월잔액 */}
          <TableCell className="text-right">
            {item.carryoverBalance !== 0 && (
              <span className={item.carryoverBalance < 0 ? 'text-red-600' : ''}>
                {formatAmount(item.carryoverBalance)}
              </span>
            )}
          </TableCell>
          {/* 매출 */}
          <TableCell className="text-right">{formatAmount(item.sales)}</TableCell>
          {/* 수금 */}
          <TableCell className="text-right">{formatAmount(item.collection)}</TableCell>
          {/* 잔액 */}
          <TableCell className="text-right">
            <span className={item.balance < 0 ? 'text-red-600' : ''}>
              {formatAmount(item.balance)}
            </span>
          </TableCell>
          {/* 결제일 */}
          <TableCell className="text-center">{item.paymentDate}</TableCell>
        </TableRow>
      ),

      // 모바일 카드 렌더링
      renderMobileCard: (
        item: VendorLedgerItem,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<VendorLedgerItem>
      ) => (
        <MobileCard
          key={item.id}
          title={item.vendorName}
          subtitle={`결제일: ${item.paymentDate || '-'}`}
          isSelected={handlers.isSelected}
          onToggle={handlers.onToggle}
          onClick={() => handleRowClick(item)}
          details={[
            { label: '이월잔액', value: formatAmount(item.carryoverBalance) || '-' },
            { label: '매출', value: formatAmount(item.sales) || '-' },
            { label: '수금', value: formatAmount(item.collection) || '-' },
            { label: '잔액', value: formatAmount(item.balance) || '-' },
          ]}
        />
      ),
    }),
    [
      data,
      pagination,
      summary,
      totals,
      startDate,
      endDate,
      isLoading,
      handleRowClick,
      handleExcelDownload,
    ]
  );

  return (
    <UniversalListPage
      config={config}
      initialData={data}
      externalPagination={{
        currentPage,
        totalPages: pagination.lastPage,
        totalItems: pagination.total,
        itemsPerPage: 20,
        onPageChange: setCurrentPage,
      }}
    />
  );
}