'use client';

/**
 * 매출관리 - UniversalListPage 마이그레이션
 *
 * 기존 IntegratedListTemplateV2 → UniversalListPage config 기반으로 변환
 * - 클라이언트 사이드 필터링 (검색, 필터, 정렬)
 * - Stats 카드 (단순 표시, 클릭 없음)
 * - beforeTableContent (계정과목명 Select + 저장 버튼)
 * - filterConfig (4개 필터: 거래처, 매출유형, 발행여부, 정렬) - PC 인라인, 모바일 바텀시트
 * - tableFooter (합계 행)
 * - Switch 토글 (세금계산서/거래명세서 발행)
 * - 커스텀 Dialog (계정과목명 저장) - UniversalListPage 외부 유지
 * - deleteConfirmMessage로 삭제 다이얼로그 처리
 */

import { useState, useMemo, useCallback, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';
import {
  Receipt,
  Save,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Switch } from '@/components/ui/switch';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { TableRow, TableCell } from '@/components/ui/table';
import {
  UniversalListPage,
  type UniversalListConfig,
  type SelectionHandlers,
  type RowClickHandlers,
  type StatCard,
  type FilterFieldConfig,
} from '@/components/templates/UniversalListPage';
import { MobileCard } from '@/components/organisms/MobileCard';
import { AccountSubjectSelect } from '@/components/accounting/common';
import type { SalesRecord } from './types';
import {
  SORT_OPTIONS,
  TAX_INVOICE_FILTER_OPTIONS,
  TRANSACTION_STATEMENT_FILTER_OPTIONS,
} from './types';
import { getSales, deleteSale, toggleSaleIssuance } from './actions';
import { useDateRange } from '@/hooks';
import {
  createDeleteItemHandler,
  extractUniqueOptions,
  createDateAmountSortFn,
  computeMonthlyTotal,
  type SortDirection,
} from '../shared';
import { formatNumber } from '@/lib/utils/amount';
import { applyFilters, enumFilter } from '@/lib/utils/search';

// ===== 테이블 컬럼 정의 =====
const tableColumns = [
  { key: 'no', label: '번호', className: 'text-center w-[60px]' },
  { key: 'salesNo', label: '매출번호', sortable: true, copyable: true },
  { key: 'salesDate', label: '매출일', sortable: true, copyable: true },
  { key: 'vendorName', label: '거래처', sortable: true, copyable: true },
  { key: 'totalSupplyAmount', label: '공급가액', className: 'text-right', sortable: true, copyable: true },
  { key: 'totalVat', label: '부가세', className: 'text-right', sortable: true, copyable: true },
  { key: 'totalAmount', label: '합계금액', className: 'text-right', sortable: true, copyable: true },
  { key: 'taxInvoice', label: '세금계산서 발행완료', className: 'text-center' },
  { key: 'transactionStatement', label: '거래명세서 발행완료', className: 'text-center' },
];

// ===== Props 타입 =====
interface SalesManagementProps {
  initialData: SalesRecord[];
  initialPagination: {
    currentPage: number;
    lastPage: number;
    perPage: number;
    total: number;
  };
}

export function SalesManagement({ initialData, initialPagination }: SalesManagementProps) {
  const router = useRouter();

  // ===== 외부 상태 (UniversalListPage 외부에서 관리) =====
  const { startDate, endDate, setStartDate, setEndDate } = useDateRange('currentYear');
  const [salesData, setSalesData] = useState<SalesRecord[]>(initialData || []);
  const [pagination, setPagination] = useState(initialPagination);
  const [currentPage, setCurrentPage] = useState(initialPagination.currentPage);
  const [isLoading, setIsLoading] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');

  // 필터 초기값 (filterConfig 기반 - ULP가 내부 state로 관리)
  const initialFilterValues: Record<string, string | string[]> = {
    vendor: 'all',
    taxInvoice: 'all',
    transactionStatement: 'all',
    sort: 'latest',
  };

  // 계정과목명 저장 다이얼로그
  const [selectedAccountSubject, setSelectedAccountSubject] = useState<string>('');
  const [showSaveDialog, setShowSaveDialog] = useState(false);
  const [selectedItemsForSave, setSelectedItemsForSave] = useState<Set<string>>(new Set());

  // ===== 통계 계산 =====
  const stats = useMemo(() => {
    const totalSalesAmount = salesData.reduce((sum, d) => sum + d.totalAmount, 0);
    const monthlyAmount = computeMonthlyTotal(salesData, 'salesDate', 'totalAmount');
    const taxInvoicePendingCount = salesData.filter(d => !d.taxInvoiceIssued).length;
    const transactionStatementPendingCount = salesData.filter(d => !d.transactionStatementIssued).length;
    return { totalSalesAmount, monthlyAmount, taxInvoicePendingCount, transactionStatementPendingCount };
  }, [salesData]);

  // ===== 거래처 목록 (필터용) =====
  const vendorOptions = useMemo(
    () => extractUniqueOptions(salesData, 'vendorName', { includeAll: false }),
    [salesData]
  );

  // ===== filterConfig 정의 =====
  const filterConfig: FilterFieldConfig[] = useMemo(() => [
    {
      key: 'vendor',
      label: '거래처',
      type: 'single',
      options: vendorOptions,
      allOptionLabel: '거래처 전체',
    },
    {
      key: 'taxInvoice',
      label: '세금계산서 발행여부',
      type: 'single',
      options: TAX_INVOICE_FILTER_OPTIONS.filter(o => o.value !== 'all'),
      allOptionLabel: '세금계산서 전체',
    },
    {
      key: 'transactionStatement',
      label: '거래명세서 발행여부',
      type: 'single',
      options: TRANSACTION_STATEMENT_FILTER_OPTIONS.filter(o => o.value !== 'all'),
      allOptionLabel: '거래명세서 전체',
    },
    {
      key: 'sort',
      label: '정렬',
      type: 'single',
      options: SORT_OPTIONS,
    },
  ], [vendorOptions]);

  // 참고: 필터 변경/리셋은 UniversalListPage가 filterConfig 기반으로 내부 처리

  // ===== API 데이터 로드 =====
  const loadData = useCallback(async (page: number = 1) => {
    setIsLoading(true);
    try {
      const result = await getSales({
        search: searchQuery || undefined,
        startDate,
        endDate,
        perPage: 100,
        page,
      });

      if (result.success) {
        setSalesData(result.data);
        setPagination(result.pagination);
        setCurrentPage(result.pagination.currentPage);
      } else {
        toast.error(result.error || '데이터를 불러오는데 실패했습니다.');
      }
    } catch {
      toast.error('데이터를 불러오는데 실패했습니다.');
    } finally {
      setIsLoading(false);
    }
  }, [searchQuery, startDate, endDate]);

  // initialData가 비어있으면 자동 로드
  useEffect(() => {
    if ((!initialData || initialData.length === 0) && !isLoading) {
      loadData();
    }
   
  }, []);

  // ===== 페이지 변경 =====
  const handlePageChange = useCallback((page: number) => {
    loadData(page);
  }, [loadData]);

  // ===== 핸들러 =====
  const handleRowClick = useCallback((item: SalesRecord) => {
    router.push(`/ko/accounting/sales/${item.id}?mode=view`);
  }, [router]);

  const handleCreate = useCallback(() => {
    router.push('/ko/accounting/sales?mode=new');
  }, [router]);

  // 토글 핸들러 (Optimistic UI: 먼저 UI 업데이트 → API 호출 → 실패 시 롤백)
  const handleTaxInvoiceToggle = useCallback(async (itemId: string, checked: boolean) => {
    setSalesData(prev => prev.map(item =>
      item.id === itemId ? { ...item, taxInvoiceIssued: checked } : item
    ));
    const result = await toggleSaleIssuance(itemId, 'taxInvoiceIssued', checked);
    if (!result.success) {
      setSalesData(prev => prev.map(item =>
        item.id === itemId ? { ...item, taxInvoiceIssued: !checked } : item
      ));
      toast.error(result.error || '세금계산서 발행 상태 변경에 실패했습니다.');
    }
  }, []);

  const handleTransactionStatementToggle = useCallback(async (itemId: string, checked: boolean) => {
    setSalesData(prev => prev.map(item =>
      item.id === itemId ? { ...item, transactionStatementIssued: checked } : item
    ));
    const result = await toggleSaleIssuance(itemId, 'transactionStatementIssued', checked);
    if (!result.success) {
      setSalesData(prev => prev.map(item =>
        item.id === itemId ? { ...item, transactionStatementIssued: !checked } : item
      ));
      toast.error(result.error || '거래명세서 발행 상태 변경에 실패했습니다.');
    }
  }, []);

  // 계정과목명 저장 핸들러
  const handleSaveAccountSubject = useCallback((selectedItems: Set<string>) => {
    if (selectedItems.size === 0) {
      toast.warning('변경할 매출 항목을 선택해주세요.');
      return;
    }
    setSelectedItemsForSave(selectedItems);
    setShowSaveDialog(true);
  }, []);

  const handleConfirmSaveAccountSubject = useCallback(() => {
    // TODO: API 호출로 저장
    setShowSaveDialog(false);
    setSelectedItemsForSave(new Set());
    toast.success('계정과목명이 변경되었습니다.');
  }, [selectedAccountSubject]);

  // ===== 테이블 합계 계산 =====
  const tableTotals = useMemo(() => {
    const totalSupplyAmount = salesData.reduce((sum, item) => sum + item.totalSupplyAmount, 0);
    const totalVat = salesData.reduce((sum, item) => sum + item.totalVat, 0);
    const totalAmount = salesData.reduce((sum, item) => sum + item.totalAmount, 0);
    return { totalSupplyAmount, totalVat, totalAmount };
  }, [salesData]);

  // ===== UniversalListPage Config =====
  const config: UniversalListConfig<SalesRecord> = useMemo(
    () => ({
      // 페이지 기본 정보
      title: '매출관리',
      description: '매출 내역을 등록하고 관리합니다',
      icon: Receipt,
      basePath: '/accounting/sales',

      // ID 추출
      idField: 'id',

      // API 액션
      actions: {
        getList: async () => {
          const result = await getSales({ perPage: 100, page: currentPage });
          if (result.success) {
            setSalesData(result.data);
            setPagination(result.pagination);
            return { success: true, data: result.data, totalCount: result.pagination.total };
          }
          return { success: true, data: salesData, totalCount: salesData.length };
        },
        deleteItem: createDeleteItemHandler(deleteSale, setSalesData, '매출이 삭제되었습니다.'),
      },

      // 테이블 컬럼
      columns: tableColumns,

      // 클라이언트 사이드 필터링
      clientSideFiltering: true,
      itemsPerPage: 20,

      // 데이터 변경 콜백
      onDataChange: (data) => setSalesData(data),

      // 검색 필터
      searchPlaceholder: '매출번호, 거래처명, 비고 검색...',
      searchFilter: (item, searchValue) => {
        const search = searchValue.toLowerCase();
        return (
          item.salesNo.toLowerCase().includes(search) ||
          item.vendorName.toLowerCase().includes(search) ||
          item.note.toLowerCase().includes(search)
        );
      },

      // 커스텀 필터 함수 (filterConfig 기반 - ULP의 filters state에서 값 전달)
      // 검색은 searchFilter에서 처리하므로 여기서는 필터만 처리
      customFilterFn: (items, fv) => {
        if (!items || items.length === 0) return items;
        const taxInvoiceVal = fv.taxInvoice as string;
        const transactionStatementVal = fv.transactionStatement as string;

        let result = applyFilters(items, [
          enumFilter('vendorName', fv.vendor as string),
        ]);

        // 세금계산서 발행여부 필터
        if (taxInvoiceVal === 'issued') {
          result = result.filter(item => item.taxInvoiceIssued);
        } else if (taxInvoiceVal === 'notIssued') {
          result = result.filter(item => !item.taxInvoiceIssued);
        }

        // 거래명세서 발행여부 필터
        if (transactionStatementVal === 'issued') {
          result = result.filter(item => item.transactionStatementIssued);
        } else if (transactionStatementVal === 'notIssued') {
          result = result.filter(item => !item.transactionStatementIssued);
        }

        return result;
      },

      // 커스텀 정렬 함수
      customSortFn: (items, fv) =>
        createDateAmountSortFn<SalesRecord>('salesDate', 'totalAmount', (fv.sort as SortDirection) ?? 'latest')(items),

      // 검색창 (공통 컴포넌트에서 자동 생성)
      hideSearch: true,
      searchValue: searchQuery,
      onSearchChange: setSearchQuery,

      // 공통 헤더 옵션
      dateRangeSelector: {
        enabled: true,
        showPresets: true,
        startDate,
        endDate,
        onStartDateChange: setStartDate,
        onEndDateChange: setEndDate,
      },
      // 헤더 액션 (계정과목명 검색 Select + 저장 버튼)
      headerActions: ({ selectedItems }) => (
        <div className="flex items-center gap-2">
          <span className="text-sm font-medium text-gray-700 whitespace-nowrap">계정과목명</span>
          <AccountSubjectSelect
            value={selectedAccountSubject}
            onValueChange={setSelectedAccountSubject}
            category="revenue"
            placeholder="계정과목 선택"
            size="sm"
            className="min-w-[180px] w-auto"
          />
          <Button onClick={() => handleSaveAccountSubject(selectedItems)} size="sm">
            <Save className="h-4 w-4 mr-1" />
            저장
          </Button>
        </div>
      ),
      createButton: {
        label: '매출 등록',
        onClick: handleCreate,
      },

      // Stats 카드
      computeStats: (): StatCard[] => [
        { label: '총 매출', value: `${formatNumber(stats.totalSalesAmount)}원`, icon: Receipt, iconColor: 'text-blue-500' },
        { label: '당월 매출', value: `${formatNumber(stats.monthlyAmount)}원`, icon: Receipt, iconColor: 'text-green-500' },
        { label: '세금계산서 발행대기', value: `${stats.taxInvoicePendingCount}건`, icon: Receipt, iconColor: 'text-orange-500' },
        { label: '거래명세서 발행대기', value: `${stats.transactionStatementPendingCount}건`, icon: Receipt, iconColor: 'text-orange-500' },
      ],

      // 필터 설정 (filterConfig 사용 - PC 인라인, 모바일 바텀시트)
      filterConfig,
      initialFilters: initialFilterValues,
      filterTitle: '매출 필터',

      // 테이블 하단 합계 행
      tableFooter: (
        <TableRow className="bg-muted/50 font-medium">
          <TableCell className="text-center"></TableCell>
          <TableCell className="text-center"></TableCell>
          <TableCell className="font-bold">합계</TableCell>
          <TableCell></TableCell>
          <TableCell></TableCell>
          <TableCell className="text-right font-bold">{formatNumber(tableTotals.totalSupplyAmount)}</TableCell>
          <TableCell className="text-right font-bold">{formatNumber(tableTotals.totalVat)}</TableCell>
          <TableCell className="text-right font-bold">{formatNumber(tableTotals.totalAmount)}</TableCell>
          <TableCell></TableCell>
          <TableCell></TableCell>
        </TableRow>
      ),

      // 삭제 확인 메시지
      deleteConfirmMessage: {
        title: '매출 삭제',
        description: '이 매출 내역을 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.',
      },

      // 테이블 행 렌더링
      renderTableRow: (
        item: SalesRecord,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<SalesRecord>
      ) => (
        <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>
          <TableCell className="text-center text-sm text-gray-500">{globalIndex}</TableCell>
          <TableCell className="text-sm font-medium">{item.salesNo}</TableCell>
          <TableCell>{item.salesDate}</TableCell>
          <TableCell>{item.vendorName}</TableCell>
          <TableCell className="text-right">{formatNumber(item.totalSupplyAmount)}</TableCell>
          <TableCell className="text-right">{formatNumber(item.totalVat)}</TableCell>
          <TableCell className="text-right font-medium">{formatNumber(item.totalAmount)}</TableCell>
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            <div className="flex items-center justify-center gap-1">
              <Switch
                checked={item.taxInvoiceIssued}
                onCheckedChange={(checked) => handleTaxInvoiceToggle(item.id, checked)}
                className="data-[state=checked]:bg-orange-500"
              />
              {item.taxInvoiceIssued && <span className="text-xs text-orange-500 font-medium">발행</span>}
            </div>
          </TableCell>
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            <div className="flex items-center justify-center gap-1">
              <Switch
                checked={item.transactionStatementIssued}
                onCheckedChange={(checked) => handleTransactionStatementToggle(item.id, checked)}
                className="data-[state=checked]:bg-orange-500"
              />
              {item.transactionStatementIssued && <span className="text-xs text-orange-500 font-medium">발행</span>}
            </div>
          </TableCell>
        </TableRow>
      ),

      // 모바일 카드 렌더링
      renderMobileCard: (
        item: SalesRecord,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<SalesRecord>
      ) => (
        <MobileCard
          key={item.id}
          title={item.vendorName}
          subtitle={item.salesNo}
          isSelected={handlers.isSelected}
          onToggle={handlers.onToggle}
          onClick={() => handleRowClick(item)}
          details={[
            { label: '매출일', value: item.salesDate },
            { label: '매출금액', value: `${formatNumber(item.totalAmount)}원` },
            { label: '미수금액', value: item.outstandingAmount > 0 ? `${formatNumber(item.outstandingAmount)}원` : '-' },
          ]}
        />
      ),
    }),
    [
      salesData,
      currentPage,
      startDate,
      endDate,
      stats,
      filterConfig,
      selectedAccountSubject,
      tableTotals,
      handleRowClick,
      handleCreate,
      handleTaxInvoiceToggle,
      handleTransactionStatementToggle,
      handleSaveAccountSubject,
    ]
  );

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

      {/* 계정과목명 저장 확인 다이얼로그 */}
      <Dialog open={showSaveDialog} onOpenChange={setShowSaveDialog}>
        <DialogContent className="sm:max-w-[425px]">
          <DialogHeader>
            <DialogTitle>계정과목명 변경</DialogTitle>
            <DialogDescription>
              {selectedItemsForSave.size}개의 매출유형을 선택한 계정과목으로 모두 변경하시겠습니까?
            </DialogDescription>
          </DialogHeader>
          <DialogFooter className="gap-3">
            <Button variant="outline" onClick={() => setShowSaveDialog(false)}>
              취소
            </Button>
            <Button
              onClick={handleConfirmSaveAccountSubject}
              className="bg-blue-500 hover:bg-blue-600"
            >
              확인
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}