'use client';

/**
 * 입출금 계좌조회 - UniversalListPage 마이그레이션
 *
 * 기존 IntegratedListTemplateV2 → UniversalListPage config 기반으로 변환
 * - 서버 사이드 필터링/페이지네이션
 * - dateRangeSelector (헤더 액션)
 * - beforeTableContent: 새로고침 버튼
 * - tableHeaderActions: 3개 Select 필터 (결제계좌, 입출금유형, 정렬)
 * - tableFooter: 합계 행
 * - 수정 버튼 (입금/출금 상세 페이지 이동)
 */

import { useState, useMemo, useCallback, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { format, startOfMonth, endOfMonth } from 'date-fns';
import { Building2, Pencil, RefreshCw, Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Badge } from '@/components/ui/badge';
import { TableRow, TableCell } from '@/components/ui/table';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { MobileCard } from '@/components/organisms/MobileCard';
import {
  UniversalListPage,
  type UniversalListConfig,
  type SelectionHandlers,
  type RowClickHandlers,
  type StatCard,
} from '@/components/templates/UniversalListPage';
import type { BankTransaction, SortOption } from './types';
import {
  TRANSACTION_KIND_LABELS,
  DEPOSIT_TYPE_LABELS,
  WITHDRAWAL_TYPE_LABELS,
  SORT_OPTIONS,
  TRANSACTION_TYPE_FILTER_OPTIONS,
} from './types';
import {
  getBankTransactionList,
  getBankTransactionSummary,
  getBankAccountOptions,
} from './actions';
import { isNextRedirectError } from '@/lib/utils/redirect-error';

// ===== 테이블 컬럼 정의 =====
const tableColumns = [
  { key: 'bankName', label: '은행명' },
  { key: 'accountName', label: '계좌명' },
  { key: 'transactionDate', label: '거래일시' },
  { key: 'type', label: '구분', className: 'text-center' },
  { key: 'note', label: '적요' },
  { key: 'vendorName', label: '거래처' },
  { key: 'depositorName', label: '입금자/수취인' },
  { key: 'depositAmount', label: '입금', className: 'text-right' },
  { key: 'withdrawalAmount', label: '출금', className: 'text-right' },
  { key: 'balance', label: '잔액', className: 'text-right' },
  { key: 'transactionType', label: '입출금 유형', className: 'text-center' },
  { key: 'actions', label: '작업', className: 'text-center w-[80px]' },
];

// ===== Props =====
interface BankTransactionInquiryProps {
  initialData?: BankTransaction[];
  initialSummary?: {
    totalDeposit: number;
    totalWithdrawal: number;
    depositUnsetCount: number;
    withdrawalUnsetCount: number;
  };
  initialPagination?: {
    currentPage: number;
    lastPage: number;
    perPage: number;
    total: number;
  };
}

export function BankTransactionInquiry({
  initialData = [],
  initialSummary,
  initialPagination,
}: BankTransactionInquiryProps) {
  const router = useRouter();

  // ===== 외부 상태 (UniversalListPage 외부에서 관리) =====
  const [data, setData] = useState<BankTransaction[]>(initialData);
  const [summary, setSummary] = useState(
    initialSummary || { totalDeposit: 0, totalWithdrawal: 0, depositUnsetCount: 0, withdrawalUnsetCount: 0 }
  );
  const [pagination, setPagination] = useState(
    initialPagination || { currentPage: 1, lastPage: 1, perPage: 20, total: 0 }
  );
  const [accountOptions, setAccountOptions] = useState<{ value: string; label: string }[]>([
    { value: 'all', label: '전체' },
  ]);

  // 필터 상태
  const [searchQuery, setSearchQuery] = useState('');
  const [sortOption, setSortOption] = useState<SortOption>('latest');
  const [accountFilter, setAccountFilter] = useState<string>('all');
  const [transactionTypeFilter, setTransactionTypeFilter] = useState<string>('all');
  const [currentPage, setCurrentPage] = useState(initialPagination?.currentPage || 1);
  const [isLoading, setIsLoading] = useState(!initialData.length);

  // 날짜 범위 상태
  const [startDate, setStartDate] = useState(() => format(startOfMonth(new Date()), 'yyyy-MM-dd'));
  const [endDate, setEndDate] = useState(() => format(endOfMonth(new Date()), 'yyyy-MM-dd'));

  // ===== 데이터 로드 =====
  const loadData = useCallback(async () => {
    setIsLoading(true);
    try {
      const sortMapping: Record<SortOption, { sortBy: string; sortDir: 'asc' | 'desc' }> = {
        latest: { sortBy: 'transaction_date', sortDir: 'desc' },
        oldest: { sortBy: 'transaction_date', sortDir: 'asc' },
        amountHigh: { sortBy: 'amount', sortDir: 'desc' },
        amountLow: { sortBy: 'amount', sortDir: 'asc' },
      };
      const sortParams = sortMapping[sortOption];

      const [listResult, summaryResult, accountsResult] = await Promise.all([
        getBankTransactionList({
          page: currentPage,
          perPage: 20,
          startDate,
          endDate,
          bankAccountId: accountFilter !== 'all' ? parseInt(accountFilter, 10) : undefined,
          transactionType: transactionTypeFilter !== 'all' ? transactionTypeFilter : undefined,
          search: searchQuery || undefined,
          sortBy: sortParams.sortBy,
          sortDir: sortParams.sortDir,
        }),
        getBankTransactionSummary({ startDate, endDate }),
        getBankAccountOptions(),
      ]);

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

      if (summaryResult.success && summaryResult.data) {
        setSummary(summaryResult.data);
      }

      if (accountsResult.success) {
        setAccountOptions([
          { value: 'all', label: '전체' },
          ...accountsResult.data.map((acc) => ({ value: String(acc.id), label: acc.label })),
        ]);
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('[BankTransactionInquiry] loadData error:', error);
    } finally {
      setIsLoading(false);
    }
  }, [currentPage, startDate, endDate, accountFilter, transactionTypeFilter, searchQuery, sortOption]);

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

  // ===== 핸들러 =====
  const handleEditClick = useCallback(
    (item: BankTransaction) => {
      if (item.type === 'deposit') {
        router.push(`/ko/accounting/deposits/${item.sourceId}?mode=edit`);
      } else {
        router.push(`/ko/accounting/withdrawals/${item.sourceId}?mode=edit`);
      }
    },
    [router]
  );

  const handleRefresh = useCallback(() => {
    loadData();
  }, [loadData]);

  // ===== 유형 라벨 가져오기 =====
  const getTransactionTypeLabel = useCallback((item: BankTransaction) => {
    if (!item.transactionType) return '미설정';
    if (item.type === 'deposit') {
      return DEPOSIT_TYPE_LABELS[item.transactionType as keyof typeof DEPOSIT_TYPE_LABELS] || item.transactionType;
    }
    return WITHDRAWAL_TYPE_LABELS[item.transactionType as keyof typeof WITHDRAWAL_TYPE_LABELS] || item.transactionType;
  }, []);

  // ===== 테이블 합계 계산 =====
  const tableTotals = useMemo(() => {
    const totalDeposit = data.reduce((sum, item) => sum + item.depositAmount, 0);
    const totalWithdrawal = data.reduce((sum, item) => sum + item.withdrawalAmount, 0);
    return { totalDeposit, totalWithdrawal };
  }, [data]);

  // ===== UniversalListPage Config =====
  const config: UniversalListConfig<BankTransaction> = useMemo(
    () => ({
      // 페이지 기본 정보
      title: '입출금 계좌조회',
      description: '은행 계좌 정보와 입출금 내역을 조회할 수 있습니다',
      icon: Building2,
      basePath: '/accounting/bank-transactions',

      // ID 추출
      idField: 'id',

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

      // 테이블 컬럼
      columns: tableColumns,

      // 서버 사이드 필터링 (클라이언트 사이드 아님)
      clientSideFiltering: false,
      itemsPerPage: 20,

      // 검색
      searchPlaceholder: '은행명, 계좌명, 거래처, 입금자/수취인 검색...',
      onSearchChange: setSearchQuery,

      // 필터 설정 (모바일용)
      filterConfig: [
        {
          key: 'account',
          label: '결제계좌',
          type: 'single',
          options: accountOptions.filter((o) => o.value !== 'all'),
        },
        {
          key: 'transactionType',
          label: '입출금유형',
          type: 'single',
          options: TRANSACTION_TYPE_FILTER_OPTIONS.filter((o) => o.value !== 'all').map((o) => ({
            value: o.value,
            label: o.label,
          })),
        },
        {
          key: 'sortBy',
          label: '정렬',
          type: 'single',
          options: SORT_OPTIONS.map((o) => ({
            value: o.value,
            label: o.label,
          })),
        },
      ],
      initialFilters: {
        account: 'all',
        transactionType: 'all',
        sortBy: 'latest',
      },
      filterTitle: '계좌 필터',

      // 날짜 선택기 (헤더 액션)
      dateRangeSelector: {
        enabled: true,
        startDate,
        endDate,
        onStartDateChange: setStartDate,
        onEndDateChange: setEndDate,
      },

      // 헤더 액션: 새로고침 버튼
      headerActions: () => (
        <Button variant="outline" size="sm" onClick={handleRefresh} disabled={isLoading}>
          {isLoading ? (
            <Loader2 className="h-4 w-4 mr-1 animate-spin" />
          ) : (
            <RefreshCw className="h-4 w-4 mr-1" />
          )}
          {isLoading ? '조회중...' : '새로고침'}
        </Button>
      ),

      // 테이블 헤더 액션 (3개 필터)
      tableHeaderActions: () => (
        <div className="flex items-center gap-2 flex-wrap">
          {/* 결제계좌 필터 */}
          <Select value={accountFilter} onValueChange={setAccountFilter}>
            <SelectTrigger className="w-[180px]">
              <SelectValue placeholder="결제계좌" />
            </SelectTrigger>
            <SelectContent>
              {accountOptions.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          {/* 입출금유형 필터 */}
          <Select value={transactionTypeFilter} onValueChange={setTransactionTypeFilter}>
            <SelectTrigger className="w-[130px]">
              <SelectValue placeholder="입출금유형" />
            </SelectTrigger>
            <SelectContent>
              {TRANSACTION_TYPE_FILTER_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          {/* 정렬 */}
          <Select value={sortOption} onValueChange={(value) => setSortOption(value as SortOption)}>
            <SelectTrigger className="w-[120px]">
              <SelectValue placeholder="정렬" />
            </SelectTrigger>
            <SelectContent>
              {SORT_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      ),

      // 테이블 푸터 (합계 행)
      tableFooter: (
        <TableRow className="bg-muted/50 font-medium">
          <TableCell className="text-center" />
          <TableCell className="font-bold">합계</TableCell>
          <TableCell />
          <TableCell />
          <TableCell />
          <TableCell />
          <TableCell />
          <TableCell />
          <TableCell />
          <TableCell className="text-right font-bold text-blue-600">
            {tableTotals.totalDeposit.toLocaleString()}
          </TableCell>
          <TableCell className="text-right font-bold text-red-600">
            {tableTotals.totalWithdrawal.toLocaleString()}
          </TableCell>
          <TableCell />
          <TableCell />
          <TableCell />
        </TableRow>
      ),

      // Stats 카드
      computeStats: (): StatCard[] => [
        {
          label: '입금',
          value: `${summary.totalDeposit.toLocaleString()}원`,
          icon: Building2,
          iconColor: 'text-blue-500',
        },
        {
          label: '출금',
          value: `${summary.totalWithdrawal.toLocaleString()}원`,
          icon: Building2,
          iconColor: 'text-red-500',
        },
        {
          label: '입금 유형 미설정',
          value: `${summary.depositUnsetCount}건`,
          icon: Building2,
          iconColor: 'text-green-500',
        },
        {
          label: '출금 유형 미설정',
          value: `${summary.withdrawalUnsetCount}건`,
          icon: Building2,
          iconColor: 'text-orange-500',
        },
      ],

      // 테이블 행 렌더링
      renderTableRow: (
        item: BankTransaction,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<BankTransaction>
      ) => {
        const isTypeUnset = item.transactionType === 'unset';

        return (
          <TableRow key={item.id} className="hover:bg-muted/50">
            {/* 체크박스 */}
            <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
              <Checkbox checked={handlers.isSelected} onCheckedChange={handlers.onToggle} />
            </TableCell>
            {/* 번호 */}
            <TableCell className="text-center">{globalIndex}</TableCell>
            {/* 은행명 */}
            <TableCell>{item.bankName}</TableCell>
            {/* 계좌명 */}
            <TableCell>{item.accountName}</TableCell>
            {/* 거래일시 */}
            <TableCell>{item.transactionDate}</TableCell>
            {/* 구분 */}
            <TableCell className="text-center">
              <Badge
                variant="outline"
                className={
                  item.type === 'deposit'
                    ? 'border-blue-300 text-blue-600 bg-blue-50'
                    : 'border-red-300 text-red-600 bg-red-50'
                }
              >
                {TRANSACTION_KIND_LABELS[item.type]}
              </Badge>
            </TableCell>
            {/* 적요 */}
            <TableCell className="text-gray-500">{item.note || '-'}</TableCell>
            {/* 거래처 */}
            <TableCell>{item.vendorName || '-'}</TableCell>
            {/* 입금자/수취인 */}
            <TableCell>{item.depositorName || '-'}</TableCell>
            {/* 입금 */}
            <TableCell className="text-right font-medium text-blue-600">
              {item.depositAmount > 0 ? item.depositAmount.toLocaleString() : '-'}
            </TableCell>
            {/* 출금 */}
            <TableCell className="text-right font-medium text-red-600">
              {item.withdrawalAmount > 0 ? item.withdrawalAmount.toLocaleString() : '-'}
            </TableCell>
            {/* 잔액 */}
            <TableCell className="text-right font-medium">{item.balance.toLocaleString()}</TableCell>
            {/* 입출금 유형 */}
            <TableCell className="text-center">
              <Badge
                variant="outline"
                className={isTypeUnset ? 'border-red-300 text-red-500 bg-red-50' : ''}
              >
                {getTransactionTypeLabel(item)}
              </Badge>
            </TableCell>
            {/* 작업 */}
            <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
              {handlers.isSelected && (
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-8 w-8 text-gray-600 hover:text-gray-700 hover:bg-gray-50"
                  onClick={() => handleEditClick(item)}
                >
                  <Pencil className="h-4 w-4" />
                </Button>
              )}
            </TableCell>
          </TableRow>
        );
      },

      // 모바일 카드 렌더링
      renderMobileCard: (
        item: BankTransaction,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<BankTransaction>
      ) => (
        <MobileCard
          key={item.id}
          title={`${item.bankName} - ${item.accountName}`}
          subtitle={item.transactionDate}
          badge={TRANSACTION_KIND_LABELS[item.type]}
          badgeVariant="outline"
          badgeClassName={
            item.type === 'deposit'
              ? 'border-blue-300 text-blue-600 bg-blue-50'
              : 'border-red-300 text-red-600 bg-red-50'
          }
          isSelected={handlers.isSelected}
          onToggle={handlers.onToggle}
          details={[
            {
              label: '입금',
              value: item.depositAmount > 0 ? `${item.depositAmount.toLocaleString()}원` : '-',
            },
            {
              label: '출금',
              value: item.withdrawalAmount > 0 ? `${item.withdrawalAmount.toLocaleString()}원` : '-',
            },
            { label: '잔액', value: `${item.balance.toLocaleString()}원` },
            { label: '거래처', value: item.vendorName || '-' },
            { label: '입출금 유형', value: getTransactionTypeLabel(item) },
          ]}
          actions={
            handlers.isSelected ? (
              <Button variant="outline" className="w-full" onClick={() => handleEditClick(item)}>
                <Pencil className="w-4 h-4 mr-2" /> 수정
              </Button>
            ) : undefined
          }
        />
      ),
    }),
    [
      data,
      pagination,
      summary,
      accountOptions,
      accountFilter,
      transactionTypeFilter,
      sortOption,
      startDate,
      endDate,
      tableTotals,
      isLoading,
      handleRefresh,
      handleEditClick,
      getTransactionTypeLabel,
    ]
  );

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