'use client';

/**
 * 어음관리 - UniversalListPage 마이그레이션
 *
 * IntegratedListTemplateV2 → UniversalListPage config 기반으로 변환
 * - 서버 사이드 필터링/페이지네이션
 * - dateRangeSelector + 등록 버튼 (headerActions)
 * - beforeTableContent: 상태 선택 + 저장 버튼 + 수취/발행 라디오
 * - tableHeaderActions: 거래처, 구분, 상태 필터
 */

import { useState, useMemo, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import { formatNumber } from '@/lib/utils/amount';
import { useDateRange } from '@/hooks';
import {
  FileText,
  Plus,
  Save,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Badge } from '@/components/ui/badge';
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
import { useDeleteDialog } from '@/hooks/useDeleteDialog';
import { TableRow, TableCell } from '@/components/ui/table';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Label } from '@/components/ui/label';
import {
  UniversalListPage,
  type UniversalListConfig,
  type TableColumn,
  type SelectionHandlers,
  type RowClickHandlers,
} from '@/components/templates/UniversalListPage';
import { ListMobileCard, InfoField } from '@/components/organisms/MobileCard';
import { toast } from 'sonner';
import type {
  BillRecord,
  BillType,
  BillStatus,
  SortOption,
} from './types';
import {
  BILL_TYPE_LABELS,
  BILL_TYPE_FILTER_OPTIONS,
  BILL_STATUS_COLORS,
  BILL_STATUS_FILTER_OPTIONS,
  getBillStatusLabel,
} from './types';
import { getBills, deleteBill, updateBillStatus } from './actions';

interface BillManagementClientProps {
  initialData: BillRecord[];
  initialPagination: {
    currentPage: number;
    lastPage: number;
    perPage: number;
    total: number;
  };
  initialVendorId?: string;
  initialBillType?: string;
}

export function BillManagementClient({
  initialData,
  initialPagination,
  initialVendorId,
  initialBillType,
}: BillManagementClientProps) {
  const router = useRouter();

  // ===== 상태 관리 =====
  const [data, setData] = useState<BillRecord[]>(initialData);
  const [pagination, setPagination] = useState(initialPagination);
  const [isLoading, setIsLoading] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [sortOption, setSortOption] = useState<SortOption>('latest');
  const [billTypeFilter, setBillTypeFilter] = useState<string>(initialBillType || 'received');
  const [vendorFilter, setVendorFilter] = useState<string>(initialVendorId || 'all');
  const [statusFilter, setStatusFilter] = useState<string>('all');
  const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
  const [currentPage, setCurrentPage] = useState(initialPagination.currentPage);
  const itemsPerPage = initialPagination.perPage;

  // 삭제 다이얼로그
  const deleteDialog = useDeleteDialog({
    onDelete: async (id) => {
      const result = await deleteBill(id);
      if (result.success) {
        // 서버에서 재조회 (로컬 필터링 대신 - 페이지네이션 정합성 보장)
        await loadData(currentPage);
        setSelectedItems(prev => {
          const newSet = new Set(prev);
          newSet.delete(id);
          return newSet;
        });
      }
      return result;
    },
    entityName: '어음',
  });

  // 날짜 범위 상태
  const { startDate, endDate, setStartDate, setEndDate } = useDateRange('currentYear');

  // ===== API 데이터 로드 =====
  const loadData = useCallback(async (page: number = 1) => {
    setIsLoading(true);
    try {
      const result = await getBills({
        search: searchQuery || undefined,
        billType: billTypeFilter !== 'all' ? billTypeFilter : undefined,
        status: statusFilter !== 'all' ? statusFilter : undefined,
        clientId: vendorFilter !== 'all' ? vendorFilter : undefined,
        issueStartDate: startDate,
        issueEndDate: endDate,
        sortBy: sortOption === 'latest' || sortOption === 'oldest' ? 'issue_date' : sortOption === 'amountHigh' || sortOption === 'amountLow' ? 'amount' : 'maturity_date',
        sortDir: sortOption === 'oldest' || sortOption === 'amountLow' ? 'asc' : 'desc',
        perPage: itemsPerPage,
        page,
      });

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

  // ===== 체크박스 핸들러 =====
  const toggleSelection = useCallback((id: string) => {
    setSelectedItems(prev => {
      const newSet = new Set(prev);
      if (newSet.has(id)) newSet.delete(id);
      else newSet.add(id);
      return newSet;
    });
  }, []);

  // ===== 전체 선택 핸들러 =====
  const toggleSelectAll = useCallback(() => {
    if (selectedItems.size === data.length && data.length > 0) {
      setSelectedItems(new Set());
    } else {
      setSelectedItems(new Set(data.map(item => item.id)));
    }
  }, [selectedItems.size, data]);

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


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

  // ===== 테이블 컬럼 =====
  const tableColumns: TableColumn[] = useMemo(() => [
    { key: 'no', label: '번호', className: 'text-center w-[60px]' },
    { key: 'billNumber', label: '어음번호', sortable: true },
    { key: 'billType', label: '구분', className: 'text-center', sortable: true },
    { key: 'vendorName', label: '거래처', sortable: true },
    { key: 'amount', label: '금액', className: 'text-right', sortable: true },
    { key: 'issueDate', label: '발행일', sortable: true },
    { key: 'maturityDate', label: '만기일', sortable: true },
    { key: 'installmentCount', label: '차수', className: 'text-center', sortable: true },
    { key: 'status', label: '상태', className: 'text-center', sortable: true },
  ], []);

  // ===== 테이블 행 렌더링 =====
  const renderTableRow = useCallback((
    item: BillRecord,
    index: number,
    globalIndex: number,
    handlers: SelectionHandlers & RowClickHandlers<BillRecord>
  ) => {
    return (
      <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>{item.billNumber}</TableCell>
        <TableCell className="text-center">
          <Badge variant="outline" className={item.billType === 'received' ? 'border-blue-300 text-blue-600' : 'border-green-300 text-green-600'}>
            {BILL_TYPE_LABELS[item.billType]}
          </Badge>
        </TableCell>
        <TableCell>{item.vendorName}</TableCell>
        <TableCell className="text-right font-medium">{formatNumber(item.amount)}</TableCell>
        <TableCell>{item.issueDate}</TableCell>
        <TableCell>{item.maturityDate}</TableCell>
        <TableCell className="text-center">{item.installmentCount || '-'}</TableCell>
        <TableCell className="text-center">
          <Badge className={BILL_STATUS_COLORS[item.status]}>
            {getBillStatusLabel(item.billType, item.status)}
          </Badge>
        </TableCell>
      </TableRow>
    );
  }, [handleRowClick]);

  // ===== 모바일 카드 렌더링 =====
  const renderMobileCard = useCallback((
    item: BillRecord,
    index: number,
    globalIndex: number,
    handlers: SelectionHandlers & RowClickHandlers<BillRecord>
  ) => {
    return (
      <ListMobileCard
        id={item.id}
        title={item.billNumber}
        headerBadges={
          <>
            <Badge variant="outline" className={item.billType === 'received' ? 'border-blue-300 text-blue-600' : 'border-green-300 text-green-600'}>
              {BILL_TYPE_LABELS[item.billType]}
            </Badge>
            <Badge className={BILL_STATUS_COLORS[item.status]}>
              {getBillStatusLabel(item.billType, item.status)}
            </Badge>
          </>
        }
        isSelected={handlers.isSelected}
        onToggleSelection={handlers.onToggle}
        infoGrid={
          <div className="grid grid-cols-2 gap-3">
            <InfoField label="거래처" value={item.vendorName} />
            <InfoField label="금액" value={`${formatNumber(item.amount)}원`} />
            <InfoField label="발행일" value={item.issueDate} />
            <InfoField label="만기일" value={item.maturityDate} />
          </div>
        }
        onCardClick={() => handleRowClick(item)}
      />
    );
  }, [handleRowClick]);

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

  // ===== 저장 핸들러 =====
  const handleSave = useCallback(async () => {
    if (selectedItems.size === 0) {
      toast.warning('선택된 항목이 없습니다.');
      return;
    }

    if (statusFilter === 'all') {
      toast.warning('상태를 선택해주세요.');
      return;
    }

    setIsLoading(true);
    let successCount = 0;

    for (const id of selectedItems) {
      const result = await updateBillStatus(id, statusFilter as BillStatus);
      if (result.success) {
        successCount++;
      }
    }

    if (successCount > 0) {
      toast.success(`${successCount}건이 저장되었습니다.`);
      loadData(currentPage);
      setSelectedItems(new Set());
    } else {
      toast.error('저장에 실패했습니다.');
    }
    setIsLoading(false);
  }, [selectedItems, statusFilter, loadData, currentPage]);

  // ===== UniversalListPage Config =====
  const config: UniversalListConfig<BillRecord> = useMemo(
    () => ({
      // 페이지 기본 정보
      title: '어음관리',
      description: '어음 및 수취이음 상세 현황을 관리합니다',
      icon: FileText,
      basePath: '/accounting/bills',

      // ID 추출
      idField: 'id',

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

      // 테이블 컬럼
      columns: tableColumns,

      // 서버 사이드 필터링
      clientSideFiltering: false,
      itemsPerPage: pagination.perPage,

      // 검색
      searchPlaceholder: '어음번호, 거래처, 메모 검색...',
      onSearchChange: setSearchQuery,
      searchFilter: (item: BillRecord, search: string) => {
        const s = search.toLowerCase();
        return (
          item.billNumber?.toLowerCase().includes(s) ||
          item.vendorName?.toLowerCase().includes(s) ||
          item.note?.toLowerCase().includes(s) ||
          false
        );
      },

      // 모바일 필터 설정
      filterConfig: [
        {
          key: 'vendorFilter',
          label: '거래처',
          type: 'single',
          options: vendorOptions.filter(o => o.value !== 'all'),
        },
        {
          key: 'billType',
          label: '구분',
          type: 'single',
          options: BILL_TYPE_FILTER_OPTIONS.filter(o => o.value !== 'all'),
        },
        {
          key: 'status',
          label: '상태',
          type: 'single',
          options: BILL_STATUS_FILTER_OPTIONS.filter(o => o.value !== 'all'),
        },
      ],
      initialFilters: {
        vendorFilter: vendorFilter,
        billType: billTypeFilter,
        status: statusFilter,
      },
      filterTitle: '어음 필터',

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

      // 등록 버튼
      createButton: {
        label: '어음 등록',
        onClick: () => router.push('/ko/accounting/bills?mode=new'),
        icon: Plus,
      },

      // 헤더 액션: 상태 선택 + 저장 + 수취/발행 라디오
      headerActions: () => (
        <div className="flex items-center gap-3">
          <RadioGroup
            value={billTypeFilter}
            onValueChange={(value) => { setBillTypeFilter(value); loadData(1); }}
            className="flex items-center gap-3"
          >
            <div className="flex items-center space-x-1">
              <RadioGroupItem value="received" id="received" />
              <Label htmlFor="received" className="cursor-pointer text-sm">수취</Label>
            </div>
            <div className="flex items-center space-x-1">
              <RadioGroupItem value="issued" id="issued" />
              <Label htmlFor="issued" className="cursor-pointer text-sm">발행</Label>
            </div>
          </RadioGroup>
          <Select value={statusFilter} onValueChange={setStatusFilter}>
            <SelectTrigger className="min-w-[100px] w-auto">
              <SelectValue placeholder="상태" />
            </SelectTrigger>
            <SelectContent>
              {BILL_STATUS_FILTER_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Button onClick={handleSave} size="sm" disabled={isLoading}>
            <Save className="h-4 w-4 mr-1" />
            저장
          </Button>
        </div>
      ),

      // 테이블 헤더 액션 (필터)
      tableHeaderActions: (
        <div className="flex items-center gap-2 flex-wrap">
          <Select value={vendorFilter} onValueChange={setVendorFilter}>
            <SelectTrigger className="min-w-[120px] w-auto">
              <SelectValue placeholder="거래처명" />
            </SelectTrigger>
            <SelectContent>
              {vendorOptions.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          <Select value={billTypeFilter} onValueChange={(value) => { setBillTypeFilter(value); loadData(1); }}>
            <SelectTrigger className="min-w-[100px] w-auto">
              <SelectValue placeholder="구분" />
            </SelectTrigger>
            <SelectContent>
              {BILL_TYPE_FILTER_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          <Select value={statusFilter} onValueChange={(value) => { setStatusFilter(value); loadData(1); }}>
            <SelectTrigger className="min-w-[110px] w-auto">
              <SelectValue placeholder="보관중" />
            </SelectTrigger>
            <SelectContent>
              {BILL_STATUS_FILTER_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      ),

      // 렌더링 함수
      renderTableRow,
      renderMobileCard,
    }),
    [
      data,
      pagination,
      tableColumns,
      startDate,
      endDate,
      vendorFilter,
      vendorOptions,
      billTypeFilter,
      statusFilter,
      isLoading,
      router,
      loadData,
      handleSave,
      renderTableRow,
      renderMobileCard,
    ]
  );

  return (
    <>
      <UniversalListPage
        config={config}
        initialData={data}
        externalPagination={{
          currentPage: pagination.currentPage,
          totalPages: pagination.lastPage,
          totalItems: pagination.total,
          itemsPerPage: pagination.perPage,
          onPageChange: handlePageChange,
        }}
        externalSelection={{
          selectedItems,
          onToggleSelection: toggleSelection,
          onToggleSelectAll: toggleSelectAll,
          getItemId: (item: BillRecord) => item.id,
        }}
      />

      <DeleteConfirmDialog
        open={deleteDialog.single.isOpen}
        onOpenChange={deleteDialog.single.onOpenChange}
        onConfirm={deleteDialog.single.confirm}
        title="어음 삭제"
        description="이 어음을 삭제하시겠습니까? 이 작업은 취소할 수 없습니다."
        loading={deleteDialog.isPending}
      />
    </>
  );
}
