'use client';

/**
 * 어음관리 - UniversalListPage 마이그레이션
 *
 * 기존 IntegratedListTemplateV2 → UniversalListPage config 기반으로 변환
 * - 서버 사이드 페이지네이션 (API에서 페이지별 데이터 로드)
 * - DateRangeSelector + 등록 버튼 (dateRangeSelector + createButton)
 * - beforeTableContent (상태 필터 + 저장 + 수취/발행 라디오)
 * - tableHeaderActions (거래처, 구분, 상태 필터)
 * - 삭제 기능 (deleteConfirmMessage)
 */

import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';
import { formatNumber } from '@/lib/utils/amount';
import { getBills, deleteBill, updateBillStatus } from './actions';
import { invalidateDashboard } from '@/lib/dashboard-invalidation';
import { useDateRange } from '@/hooks';
import { extractUniqueOptions } from '../shared';
import {
  FileText,
  Plus,
  Pencil,
  Trash2,
  Save,
} 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 { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Label } from '@/components/ui/label';
import {
  UniversalListPage,
  type UniversalListConfig,
  type SelectionHandlers,
  type RowClickHandlers,
} from '@/components/templates/UniversalListPage';
import { MobileCard } from '@/components/organisms/MobileCard';
import type {
  BillRecord,
  BillStatus,
  SortOption,
} from './types';
import {
  BILL_TYPE_LABELS,
  BILL_TYPE_FILTER_OPTIONS,
  BILL_STATUS_COLORS,
  BILL_STATUS_FILTER_OPTIONS,
  getBillStatusLabel,
} from './types';

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

interface BillManagementProps {
  initialVendorId?: string;
  initialBillType?: string;
}

export function BillManagement({ initialVendorId, initialBillType }: BillManagementProps = {}) {
  const router = useRouter();

  // ===== 외부 상태 (UniversalListPage 외부에서 관리) =====
  const [billData, setBillData] = useState<BillRecord[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const isInitialLoadDone = useRef(false);
  const [isSaving, setIsSaving] = useState(false);

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

  // 인라인 필터 상태
  const [billTypeFilter, setBillTypeFilter] = useState<string>(initialBillType || 'received');
  const [vendorFilter, setVendorFilter] = useState<string>(initialVendorId || 'all');
  const [statusFilter, setStatusFilter] = useState<string>('all');
  const [sortOption, _setSortOption] = useState<SortOption>('latest');

  // 페이지네이션
  const [currentPage, setCurrentPage] = useState(1);
  const [pagination, setPagination] = useState({
    currentPage: 1,
    lastPage: 1,
    perPage: 20,
    total: 0,
  });

  // ===== API에서 데이터 로드 =====
  const loadBills = useCallback(async () => {
    if (!isInitialLoadDone.current) {
      setIsLoading(true);
    }
    try {
      const result = await getBills({
        search: undefined,
        billType: billTypeFilter !== 'all' ? billTypeFilter : undefined,
        status: statusFilter !== 'all' ? statusFilter : undefined,
        clientId: vendorFilter !== 'all' ? vendorFilter : undefined,
        issueStartDate: startDate,
        issueEndDate: endDate,
        page: currentPage,
        perPage: 20,
      });

      if (result.success) {
        setBillData(result.data);
        setPagination(result.pagination);
      } else {
        toast.error(result.error || '어음 목록을 불러오는데 실패했습니다.');
      }
    } catch {
      toast.error('서버 오류가 발생했습니다.');
    } finally {
      setIsLoading(false);
      isInitialLoadDone.current = true;
    }
  }, [billTypeFilter, statusFilter, vendorFilter, startDate, endDate, currentPage]);

  useEffect(() => {
    loadBills();
  }, [loadBills]);

  // 정렬된 데이터 (로컬 정렬)
  const sortedData = useMemo(() => {
    const result = [...billData];

    switch (sortOption) {
      case 'latest':
        result.sort((a, b) => new Date(b.issueDate).getTime() - new Date(a.issueDate).getTime());
        break;
      case 'oldest':
        result.sort((a, b) => new Date(a.issueDate).getTime() - new Date(b.issueDate).getTime());
        break;
      case 'amountHigh':
        result.sort((a, b) => b.amount - a.amount);
        break;
      case 'amountLow':
        result.sort((a, b) => a.amount - b.amount);
        break;
      case 'maturityDate':
        result.sort((a, b) => new Date(a.maturityDate).getTime() - new Date(b.maturityDate).getTime());
        break;
    }

    return result;
  }, [billData, sortOption]);

  // 거래처 목록 (필터용)
  const vendorOptions = useMemo(
    () => extractUniqueOptions(billData, 'vendorName'),
    [billData]
  );

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

  const handleEdit = useCallback((item: BillRecord) => {
    router.push(`/ko/accounting/bills/${item.id}?mode=edit`);
  }, [router]);

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

  // 저장 핸들러 (선택된 항목의 상태 일괄 변경)
  const handleSave = useCallback(async (selectedItems: Set<string>) => {
    if (selectedItems.size === 0) {
      toast.warning('선택된 항목이 없습니다.');
      return;
    }
    if (statusFilter === 'all') {
      toast.warning('변경할 상태를 선택해주세요.');
      return;
    }

    setIsSaving(true);
    try {
      let successCount = 0;
      let failCount = 0;

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

      if (successCount > 0) {
        invalidateDashboard('bill');
        toast.success(`${successCount}건의 상태가 변경되었습니다.`);
        await loadBills();
      }
      if (failCount > 0) {
        toast.error(`${failCount}건의 상태 변경에 실패했습니다.`);
      }
    } catch {
      toast.error('서버 오류가 발생했습니다.');
    } finally {
      setIsSaving(false);
    }
  }, [statusFilter, loadBills]);

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

      // ID 추출
      idField: 'id',

      // API 액션
      actions: {
        getList: async () => {
          // 이미 useEffect에서 로드됨
          return {
            success: true,
            data: sortedData,
            totalCount: pagination.total,
          };
        },
        deleteItem: async (id: string) => {
          const result = await deleteBill(id);
          if (result.success) {
            invalidateDashboard('bill');
            // 서버에서 재조회 (pagination 메타데이터 포함)
            await loadBills();
          }
          return { success: result.success, error: result.error };
        },
      },

      // 테이블 컬럼
      columns: tableColumns,

      // 서버 사이드 페이지네이션 (clientSideFiltering: false가 기본값)
      clientSideFiltering: false,
      itemsPerPage: 20,

      // 검색 필터
      searchPlaceholder: '어음번호, 거래처, 메모 검색...',

      // 필터 설정
      filterConfig: [
        {
          key: 'vendor',
          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').map(o => ({
            value: o.value,
            label: o.label,
          })),
        },
        {
          key: 'status',
          label: '상태',
          type: 'single',
          options: BILL_STATUS_FILTER_OPTIONS.filter(o => o.value !== 'all').map(o => ({
            value: o.value,
            label: o.label,
          })),
        },
      ],
      initialFilters: {
        vendor: vendorFilter,
        billType: initialBillType || 'received',
        status: statusFilter,
      },
      filterTitle: '어음 필터',

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

      // 등록 버튼
      createButton: {
        label: '어음 등록',
        onClick: handleCreate,
        icon: Plus,
      },

      // beforeTableContent: 상태 필터 + 저장 + 수취/발행 라디오
      beforeTableContent: (
        <div className="flex items-center gap-4">
          {/* 상태 필터 */}
          <Select value={statusFilter} onValueChange={setStatusFilter}>
            <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>

          {/* 수취/발행 라디오 버튼 */}
          <RadioGroup
            value={billTypeFilter}
            onValueChange={setBillTypeFilter}
            className="flex items-center gap-4"
          >
            <div className="flex items-center space-x-2">
              <RadioGroupItem value="received" id="received" />
              <Label htmlFor="received" className="cursor-pointer">수취</Label>
            </div>
            <div className="flex items-center space-x-2">
              <RadioGroupItem value="issued" id="issued" />
              <Label htmlFor="issued" className="cursor-pointer">발행</Label>
            </div>
          </RadioGroup>
        </div>
      ),

      // tableHeaderActions: 저장 버튼
      tableHeaderActions: ({ selectedItems }) => (
        <Button
          onClick={() => handleSave(selectedItems)}
          className="bg-blue-500 hover:bg-blue-600"
          disabled={isSaving}
        >
          <Save className="h-4 w-4 mr-2" />
          {isSaving ? '저장중...' : '저장'}
        </Button>
      ),

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

      // 테이블 행 렌더링
      renderTableRow: (
        item: BillRecord,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<BillRecord>
      ) => (
        <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>
          {/* 작업 */}
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            {handlers.isSelected && (
              <div className="flex items-center justify-center gap-1">
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-8 w-8 text-gray-600 hover:text-gray-700 hover:bg-gray-50"
                  onClick={() => handleEdit(item)}
                >
                  <Pencil className="h-4 w-4" />
                </Button>
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-8 w-8 text-red-500 hover:text-red-600 hover:bg-red-50"
                  onClick={() => handlers.onDelete?.(item)}
                >
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            )}
          </TableCell>
        </TableRow>
      ),

      // 모바일 카드 렌더링
      renderMobileCard: (
        item: BillRecord,
        index: number,
        globalIndex: number,
        handlers: SelectionHandlers & RowClickHandlers<BillRecord>
      ) => (
        <MobileCard
          key={item.id}
          title={item.billNumber}
          subtitle={item.vendorName}
          badge={BILL_TYPE_LABELS[item.billType]}
          badgeVariant="outline"
          isSelected={handlers.isSelected}
          onToggle={handlers.onToggle}
          onClick={() => handleRowClick(item)}
          details={[
            { label: '금액', value: `${formatNumber(item.amount)}원` },
            { label: '발행일', value: item.issueDate },
            { label: '만기일', value: item.maturityDate },
            { label: '상태', value: getBillStatusLabel(item.billType, item.status) },
          ]}
          actions={
            handlers.isSelected ? (
              <div className="flex gap-2 w-full">
                <Button variant="outline" className="flex-1" onClick={() => handleEdit(item)}>
                  <Pencil className="w-4 h-4 mr-2" /> 수정
                </Button>
                <Button
                  variant="outline"
                  className="flex-1 text-red-500 border-red-200 hover:bg-red-50 hover:text-red-600"
                  onClick={() => handlers.onDelete?.(item)}
                >
                  <Trash2 className="w-4 h-4 mr-2" /> 삭제
                </Button>
              </div>
            ) : undefined
          }
        />
      ),
    }),
    [
      sortedData,
      pagination,
      startDate,
      endDate,
      billTypeFilter,
      vendorFilter,
      statusFilter,
      isSaving,
      vendorOptions,
      handleRowClick,
      handleEdit,
      handleCreate,
      handleSave,
      loadBills,
      initialBillType,
    ]
  );

  return (
    <UniversalListPage
      config={config}
      initialData={sortedData}
      externalPagination={{
        currentPage: pagination.currentPage,
        totalPages: pagination.lastPage,
        totalItems: pagination.total,
        itemsPerPage: pagination.perPage,
        onPageChange: setCurrentPage,
      }}
      externalIsLoading={isLoading}
      onFilterChange={(filters) => {
        if (filters.vendor !== undefined) setVendorFilter(filters.vendor as string);
        if (filters.billType !== undefined) setBillTypeFilter(filters.billType as string);
        if (filters.status !== undefined) setStatusFilter(filters.status as string);
      }}
    />
  );
}