'use client';

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

import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
import { useRouter } from 'next/navigation';
import { useDateRange } from '@/hooks';
import { toast } from 'sonner';
import {
  Receipt,
  Save,
  Search,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Checkbox } from '@/components/ui/checkbox';
// Badge, getPresetStyle removed (매입유형/연결문서 컬럼 삭제)
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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  UniversalListPage,
  type UniversalListConfig,
  type SelectionHandlers,
  type RowClickHandlers,
  type StatCard,
  type FilterFieldConfig,
} from '@/components/templates/UniversalListPage';
import { MobileCard } from '@/components/organisms/MobileCard';
import type { PurchaseRecord } from './types';
import {
  SORT_OPTIONS,
  TAX_INVOICE_RECEIVED_FILTER_OPTIONS,
  ACCOUNT_SUBJECT_SELECTOR_OPTIONS,
} from './types';
import { getPurchases, togglePurchaseTaxInvoice, deletePurchase } from './actions';
import { formatNumber } from '@/lib/utils/amount';

// ===== 테이블 컬럼 정의 =====
const tableColumns = [
  { key: 'no', label: 'No.', className: 'w-[60px] text-center' },
  { key: 'purchaseNo', label: '매입번호', sortable: true },
  { key: 'purchaseDate', label: '매입일', sortable: true },
  { key: 'vendorName', label: '거래처', sortable: true },
  { key: 'supplyAmount', label: '공급가액', className: 'text-right', sortable: true },
  { key: 'vat', label: '부가세', className: 'text-right', sortable: true },
  { key: 'totalAmount', label: '합계금액', className: 'text-right', sortable: true },
  { key: 'taxInvoice', label: '세금계산서 수취 확인', className: 'text-center' },
];

export function PurchaseManagement() {
  const router = useRouter();

  // ===== 외부 상태 (UniversalListPage 외부에서 관리) =====
  const { startDate, endDate, setStartDate, setEndDate } = useDateRange('currentYear');
  const [purchaseData, setPurchaseData] = useState<PurchaseRecord[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const isInitialLoadDone = useRef(false);
  const [searchQuery, setSearchQuery] = useState('');

  // 통합 필터 상태 (filterConfig 기반)
  const [filterValues, setFilterValues] = useState<Record<string, string | string[]>>({
    vendor: 'all',
    taxInvoiceReceived: 'all',
    sort: 'latest',
  });

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

  // ===== API 데이터 로드 =====
  useEffect(() => {
    const loadData = async () => {
      if (!isInitialLoadDone.current) {
        setIsLoading(true);
      }
      try {
        const result = await getPurchases({
          startDate,
          endDate,
          perPage: 100,
        });
        if (result.success) {
          setPurchaseData(result.data);
        } else {
          toast.error(result.error || '매입 목록 조회에 실패했습니다.');
          setPurchaseData([]);
        }
      } catch {
        toast.error('매입 목록 조회 중 오류가 발생했습니다.');
        setPurchaseData([]);
      } finally {
        setIsLoading(false);
        isInitialLoadDone.current = true;
      }
    };
    loadData();
  }, [startDate, endDate]);

  // ===== 통계 계산 =====
  const stats = useMemo(() => {
    const totalPurchaseAmount = purchaseData.reduce((sum, d) => sum + d.totalAmount, 0);
    const currentMonth = new Date().getMonth();
    const currentYear = new Date().getFullYear();
    const monthlyAmount = purchaseData
      .filter(d => {
        const date = new Date(d.purchaseDate);
        return date.getMonth() === currentMonth && date.getFullYear() === currentYear;
      })
      .reduce((sum, d) => sum + d.totalAmount, 0);
    const taxInvoicePendingCount = purchaseData.filter(d => !d.taxInvoiceReceived).length;
    return { totalPurchaseAmount, monthlyAmount, taxInvoicePendingCount };
  }, [purchaseData]);

  // ===== 거래처 목록 (필터용) =====
  const vendorOptions = useMemo(() => {
    const uniqueVendors = [...new Set(purchaseData.map(d => d.vendorName).filter(v => v && v.trim() !== ''))];
    return uniqueVendors.map(v => ({ value: v, label: v }));
  }, [purchaseData]);

  // ===== filterConfig 정의 (PC/모바일 자동 분기) =====
  const filterConfig: FilterFieldConfig[] = useMemo(() => [
    {
      key: 'vendor',
      label: '거래처',
      type: 'single',
      options: vendorOptions,
      allOptionLabel: '거래처 전체',
    },
    {
      key: 'taxInvoiceReceived',
      label: '세금계산서 수취여부',
      type: 'single',
      options: TAX_INVOICE_RECEIVED_FILTER_OPTIONS.filter(o => o.value !== 'all'),
      allOptionLabel: '전체',
    },
    {
      key: 'sort',
      label: '정렬',
      type: 'single',
      options: SORT_OPTIONS,
      allOptionLabel: '최신순',
    },
  ], [vendorOptions]);

  // 필터 변경 핸들러
  const handleFilterChange = useCallback((key: string, value: string | string[]) => {
    setFilterValues(prev => ({ ...prev, [key]: value }));
  }, []);

  // 필터 초기화 핸들러
  const handleFilterReset = useCallback(() => {
    setFilterValues({
      vendor: 'all',
      taxInvoiceReceived: 'all',
      sort: 'latest',
    });
  }, []);

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

  // 토글 핸들러
  const handleTaxInvoiceToggle = useCallback(async (itemId: string, checked: boolean) => {
    setPurchaseData(prev => prev.map(item =>
      item.id === itemId ? { ...item, taxInvoiceReceived: checked } : item
    ));
    const result = await togglePurchaseTaxInvoice(itemId, checked);
    if (!result.success) {
      setPurchaseData(prev => prev.map(item =>
        item.id === itemId ? { ...item, taxInvoiceReceived: !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 호출로 저장
    toast.success('계정과목명이 변경되었습니다.');
    setShowSaveDialog(false);
    setSelectedItemsForSave(new Set());
  }, [selectedAccountSubject]);

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

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

      // ID 추출
      idField: 'id',

      // API 액션
      actions: {
        getList: async () => {
          return {
            success: true,
            data: purchaseData,
            totalCount: purchaseData.length,
          };
        },
        deleteItem: async (id: string) => {
          const result = await deletePurchase(id);
          if (result.success) {
            setPurchaseData(prev => prev.filter(item => item.id !== id));
            toast.success('매입이 삭제되었습니다.');
          }
          return { success: result.success, error: result.error };
        },
      },

      // 테이블 컬럼
      columns: tableColumns,

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

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

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

      // 커스텀 필터 함수 (filterValues 파라미터 사용)
      customFilterFn: (items, fv) => {
        if (!items || items.length === 0) return items;
        return items.filter((item) => {
          // 검색어 필터
          if (searchQuery) {
            const search = searchQuery.toLowerCase();
            const matchesSearch =
              item.purchaseNo.toLowerCase().includes(search) ||
              item.vendorName.toLowerCase().includes(search);
            if (!matchesSearch) return false;
          }

          const vendorVal = fv.vendor as string;
          const taxInvoiceReceivedVal = fv.taxInvoiceReceived as string;
          // 거래처 필터
          if (vendorVal !== 'all' && item.vendorName !== vendorVal) {
            return false;
          }
          // 세금계산서 수취여부 필터
          if (taxInvoiceReceivedVal === 'received' && !item.taxInvoiceReceived) {
            return false;
          }
          if (taxInvoiceReceivedVal === 'notReceived' && item.taxInvoiceReceived) {
            return false;
          }
          return true;
        });
      },

      // 커스텀 정렬 함수 (filterValues 파라미터 사용)
      customSortFn: (items, fv) => {
        const sorted = [...items];
        const sortVal = fv.sort as string;
        switch (sortVal) {
          case 'oldest':
            sorted.sort((a, b) => new Date(a.purchaseDate).getTime() - new Date(b.purchaseDate).getTime());
            break;
          case 'amountHigh':
            sorted.sort((a, b) => b.totalAmount - a.totalAmount);
            break;
          case 'amountLow':
            sorted.sort((a, b) => a.totalAmount - b.totalAmount);
            break;
          default: // latest
            sorted.sort((a, b) => new Date(b.purchaseDate).getTime() - new Date(a.purchaseDate).getTime());
            break;
        }
        return sorted;
      },

      // 검색창 (공통 컴포넌트에서 자동 생성)
      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>
          <Select value={selectedAccountSubject} onValueChange={setSelectedAccountSubject}>
            <SelectTrigger className="min-w-[120px] w-auto">
              <SelectValue placeholder="선택" />
            </SelectTrigger>
            <SelectContent>
              {ACCOUNT_SUBJECT_SELECTOR_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Button onClick={() => handleSaveAccountSubject(selectedItems)} size="sm">
            <Save className="h-4 w-4 mr-1" />
            저장
          </Button>
        </div>
      ),

      // 통합 필터 시스템 (PC: 인라인, 모바일: 바텀시트 자동 분기)
      filterConfig,
      initialFilters: filterValues,
      filterTitle: '매입 필터',

      // Stats 카드
      computeStats: (): StatCard[] => [
        { label: '총매입', value: `${formatNumber(stats.totalPurchaseAmount)}원`, 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-red-500' },
      ],

      // 테이블 하단 합계 행
      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 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>
        </TableRow>
      ),

      // 삭제 확인 메시지
      deleteConfirmMessage: {
        title: '매입 삭제',
        description: '이 매입 항목을 삭제하시겠습니까? 삭제된 데이터는 복구할 수 없습니다.',
      },

      // 테이블 행 렌더링
      renderTableRow: (
        item: PurchaseRecord,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<PurchaseRecord>
      ) => (
          <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">{globalIndex}</TableCell>
            <TableCell className="text-sm font-medium">{item.purchaseNo}</TableCell>
            <TableCell>{item.purchaseDate}</TableCell>
            <TableCell>{item.vendorName}</TableCell>
            <TableCell className="text-right">{formatNumber(item.supplyAmount)}</TableCell>
            <TableCell className="text-right">{formatNumber(item.vat)}</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.taxInvoiceReceived}
                  onCheckedChange={(checked) => handleTaxInvoiceToggle(item.id, checked)}
                  className="data-[state=checked]:bg-orange-500"
                />
                {item.taxInvoiceReceived && <span className="text-xs text-orange-500 font-medium">수취</span>}
              </div>
            </TableCell>
          </TableRow>
        ),

      // 모바일 카드 렌더링
      renderMobileCard: (
        item: PurchaseRecord,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<PurchaseRecord>
      ) => (
        <MobileCard
          key={item.id}
          title={item.vendorName}
          subtitle={item.purchaseNo}
          isSelected={handlers.isSelected}
          onToggle={handlers.onToggle}
          onClick={() => handleRowClick(item)}
          details={[
            { label: '매입일', value: item.purchaseDate },
            { label: '공급가액', value: `${formatNumber(item.supplyAmount)}원` },
            { label: '합계금액', value: `${formatNumber(item.totalAmount)}원` },
          ]}
        />
      ),
    }),
    [
      purchaseData,
      startDate,
      endDate,
      stats,
      filterConfig,
      filterValues,
      selectedAccountSubject,
      tableTotals,
      searchQuery,
      handleRowClick,
      handleTaxInvoiceToggle,
      handleSaveAccountSubject,
    ]
  );

  return (
    <>
      <UniversalListPage config={config} initialData={purchaseData} externalIsLoading={isLoading} />

      {/* 계정과목명 저장 확인 다이얼로그 */}
      <Dialog open={showSaveDialog} onOpenChange={setShowSaveDialog}>
        <DialogContent className="sm:max-w-[425px]">
          <DialogHeader>
            <DialogTitle>계정과목명 변경</DialogTitle>
            <DialogDescription>
              {selectedItemsForSave.size}개의 매입유형을{' '}
              <span className="font-semibold text-orange-500">
                {ACCOUNT_SUBJECT_SELECTOR_OPTIONS.find(o => o.value === selectedAccountSubject)?.label}
              </span>
              (으)로 모두 변경하시겠습니까?
            </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>
    </>
  );
}
