'use client';

import { useState, useEffect, useCallback, useMemo } from 'react';
import { toast } from 'sonner';
import { Wrench, Fuel, DollarSign, Gauge, Edit, Trash2, Download } from 'lucide-react';
import { TableRow, TableCell } from '@/components/ui/table';
import { Checkbox } from '@/components/ui/checkbox';
import { Button } from '@/components/ui/button';
import {
  IntegratedListTemplateV2,
  type TableColumn,
  type FilterFieldConfig,
  type FilterValues,
} from '@/components/templates/IntegratedListTemplateV2';
import { useColumnSettings } from '@/hooks/useColumnSettings';
import { ColumnSettingsPopover } from '@/components/molecules/ColumnSettingsPopover';
import { MobileCard, InfoField } from '@/components/organisms/MobileCard';
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
import { MaintenanceFormDialog } from './MaintenanceFormDialog';
import { getVehicleMaintenances, deleteVehicleMaintenance } from './actions';
import { getVehicleDropdown } from '../CorporateVehicles/actions';
import { downloadExcel, type ExcelColumn } from '@/lib/utils/excel-download';
import {
  type VehicleMaintenance,
  type VehicleDropdownItem,
  type MaintenanceCategory,
  MAINTENANCE_CATEGORIES,
  CATEGORY_COLORS,
  formatCurrency,
  formatDistance,
} from '../types';

const PAGE_SIZE = 20;

const TABLE_COLUMNS: TableColumn[] = [
  { key: 'no', label: '번호', className: 'text-center w-[60px]' },
  { key: 'date', label: '날짜', className: 'w-[100px]' },
  { key: 'vehicle', label: '차량', className: 'w-[140px]' },
  { key: 'category', label: '분류', className: 'text-center w-[80px]' },
  { key: 'description', label: '내용', className: 'min-w-[180px]' },
  { key: 'amount', label: '금액', className: 'text-right w-[120px]' },
  { key: 'mileage', label: '주행(km)', className: 'text-right w-[90px]' },
  { key: 'vendor', label: '업체', className: 'w-[120px]' },
  { key: 'actions', label: '관리', className: 'text-center w-[80px]' },
];

export function VehicleMaintenanceList() {
  const [data, setData] = useState<VehicleMaintenance[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [totalItems, setTotalItems] = useState(0);
  const [search, setSearch] = useState('');
  const [filterVehicle, setFilterVehicle] = useState('all');
  const [filterCategory, setFilterCategory] = useState('all');
  const [startDate, setStartDate] = useState('');
  const [endDate, setEndDate] = useState('');
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());

  // 드롭다운 차량 목록
  const [vehicles, setVehicles] = useState<VehicleDropdownItem[]>([]);

  // 모달 상태
  const [dialogOpen, setDialogOpen] = useState(false);
  const [dialogMode, setDialogMode] = useState<'create' | 'edit'>('create');
  const [selectedItem, setSelectedItem] = useState<VehicleMaintenance | null>(null);
  const [deleteOpen, setDeleteOpen] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<VehicleMaintenance | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);

  // 컬럼 설정
  const {
    visibleColumns,
    allColumnsWithVisibility,
    columnWidths,
    setColumnWidth,
    toggleColumnVisibility,
    resetSettings,
    hasHiddenColumns,
  } = useColumnSettings({
    pageId: 'vehicle-maintenance',
    columns: TABLE_COLUMNS,
    alwaysVisibleKeys: ['no', 'date', 'vehicle', 'category', 'actions'],
  });

  // 차량 드롭다운 로드
  useEffect(() => {
    getVehicleDropdown().then((result) => {
      if (result.success && result.data) {
        setVehicles(Array.isArray(result.data) ? result.data : []);
      }
    });
  }, []);

  // 데이터 조회
  const fetchData = useCallback(async () => {
    setIsLoading(true);
    try {
      const result = await getVehicleMaintenances({
        page: currentPage,
        perPage: PAGE_SIZE,
        search: search || undefined,
        vehicleId: filterVehicle,
        category: filterCategory,
        startDate: startDate || undefined,
        endDate: endDate || undefined,
      });
      if (result.success) {
        setData(result.data);
        setTotalPages(result.pagination.lastPage);
        setTotalItems(result.pagination.total);
      } else {
        toast.error(result.error || '조회에 실패했습니다.');
        setData([]);
      }
    } catch {
      toast.error('조회 중 오류가 발생했습니다.');
      setData([]);
    } finally {
      setIsLoading(false);
    }
  }, [currentPage, search, filterVehicle, filterCategory, startDate, endDate]);

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

  // 선택
  const toggleSelection = useCallback((id: string) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  }, []);

  const toggleSelectAll = useCallback(() => {
    setSelectedIds((prev) =>
      prev.size === data.length
        ? new Set()
        : new Set(data.map((item) => String(item.id)))
    );
  }, [data]);

  // 모달 핸들러
  const handleCreate = useCallback(() => {
    setSelectedItem(null);
    setDialogMode('create');
    setDialogOpen(true);
  }, []);

  const handleEdit = useCallback((item: VehicleMaintenance) => {
    setSelectedItem(item);
    setDialogMode('edit');
    setDialogOpen(true);
  }, []);

  const handleDeleteClick = useCallback((item: VehicleMaintenance) => {
    setDeleteTarget(item);
    setDeleteOpen(true);
  }, []);

  const handleDeleteConfirm = useCallback(async () => {
    if (!deleteTarget) return;
    setIsDeleting(true);
    try {
      const result = await deleteVehicleMaintenance(deleteTarget.id);
      if (result.success) {
        toast.success('비용이 삭제되었습니다.');
        setDeleteOpen(false);
        setDeleteTarget(null);
        fetchData();
      } else {
        toast.error(result.error || '삭제에 실패했습니다.');
      }
    } catch {
      toast.error('삭제 중 오류가 발생했습니다.');
    } finally {
      setIsDeleting(false);
    }
  }, [deleteTarget, fetchData]);

  // 엑셀 다운로드
  const excelColumns: ExcelColumn<VehicleMaintenance>[] = useMemo(() => [
    { header: '날짜', key: 'date', width: 12 },
    { header: '차량번호', key: 'vehicle', width: 15, transform: (_, row) => row.vehicle?.plateNumber || '-' },
    { header: '차량모델', key: 'vehicle', width: 15, transform: (_, row) => row.vehicle?.model || '-' },
    { header: '분류', key: 'category', width: 10 },
    { header: '내용', key: 'description', width: 30 },
    { header: '금액', key: 'amount', width: 15, transform: (val) => Number(val) || 0 },
    { header: '주행거리(km)', key: 'mileage', width: 15, transform: (val) => Number(val) || 0 },
    { header: '업체', key: 'vendor', width: 15 },
    { header: '메모', key: 'memo', width: 20 },
  ], []);

  const handleExcelDownload = useCallback(async () => {
    try {
      toast.info('엑셀 파일 생성 중...');
      const allData: VehicleMaintenance[] = [];
      let page = 1;
      let lastPage = 1;
      do {
        const result = await getVehicleMaintenances({
          page,
          perPage: 100,
          search: search || undefined,
          vehicleId: filterVehicle,
          category: filterCategory,
          startDate: startDate || undefined,
          endDate: endDate || undefined,
        });
        if (result.success && result.data.length > 0) {
          allData.push(...result.data);
          lastPage = result.pagination.lastPage;
        }
        page++;
      } while (page <= lastPage);

      if (allData.length > 0) {
        await downloadExcel({ data: allData as unknown as Record<string, unknown>[], columns: excelColumns as unknown as ExcelColumn[], filename: '정비이력', sheetName: '정비이력' });
        toast.success(`${allData.length}건 다운로드 완료`);
      } else {
        toast.warning('다운로드할 데이터가 없습니다.');
      }
    } catch {
      toast.error('엑셀 다운로드에 실패했습니다.');
    }
  }, [search, filterVehicle, filterCategory, startDate, endDate, excelColumns]);

  // 프론트엔드 통계 (현재 페이지 데이터 기반)
  const stats = useMemo(() => {
    const totalAmount = data.reduce((sum, v) => sum + (v.amount || 0), 0);
    const fuelAmount = data
      .filter((v) => v.category === '주유')
      .reduce((sum, v) => sum + (v.amount || 0), 0);
    const repairAmount = data
      .filter((v) => v.category === '정비')
      .reduce((sum, v) => sum + (v.amount || 0), 0);
    const otherAmount = totalAmount - fuelAmount - repairAmount;

    return [
      {
        label: '총 비용',
        value: formatCurrency(totalAmount),
        description: `${totalItems}건`,
        icon: DollarSign,
        iconColor: 'text-gray-600' as const,
      },
      {
        label: '주유비',
        value: formatCurrency(fuelAmount),
        description: `${data.filter((v) => v.category === '주유').length}건`,
        icon: Fuel,
        iconColor: 'text-amber-600' as const,
      },
      {
        label: '정비비',
        value: formatCurrency(repairAmount),
        description: `${data.filter((v) => v.category === '정비').length}건`,
        icon: Wrench,
        iconColor: 'text-blue-600' as const,
      },
      {
        label: '기타 비용',
        value: formatCurrency(otherAmount),
        description: `${data.filter((v) => v.category !== '주유' && v.category !== '정비').length}건`,
        icon: Gauge,
        iconColor: 'text-gray-600' as const,
      },
    ];
  }, [data, totalItems]);

  // 통합 필터 (PC: 인라인, 모바일: 바텀시트 자동 분기)
  const filterConfig: FilterFieldConfig[] = useMemo(() => [
    {
      key: 'vehicle',
      label: '차량',
      type: 'single' as const,
      options: vehicles.map((v) => ({ value: String(v.id), label: `${v.plateNumber} (${v.model})` })),
      allOptionLabel: '전체 차량',
    },
    {
      key: 'category',
      label: '분류',
      type: 'single' as const,
      options: MAINTENANCE_CATEGORIES.map((cat) => ({ value: cat, label: cat })),
      allOptionLabel: '전체 분류',
    },
  ], [vehicles]);

  const filterValues: FilterValues = useMemo(() => ({
    vehicle: filterVehicle,
    category: filterCategory,
  }), [filterVehicle, filterCategory]);

  const handleFilterChange = useCallback((key: string, value: string | string[]) => {
    if (key === 'vehicle') { setFilterVehicle(value as string); setCurrentPage(1); }
    if (key === 'category') { setFilterCategory(value as string); setCurrentPage(1); }
  }, []);

  const handleFilterReset = useCallback(() => {
    setFilterVehicle('all');
    setFilterCategory('all');
    setCurrentPage(1);
  }, []);

  // 테이블 행 렌더
  const renderTableRow = useCallback(
    (item: VehicleMaintenance, _index: number, globalIndex: number) => {
      const vehicleText = item.vehicle
        ? item.vehicle.plateNumber
        : '-';

      return (
        <TableRow
          key={item.id}
          className="cursor-pointer hover:bg-muted/50"
          onClick={() => handleEdit(item)}
        >
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            <Checkbox
              checked={selectedIds.has(String(item.id))}
              onCheckedChange={() => toggleSelection(String(item.id))}
            />
          </TableCell>
          <TableCell className="text-center text-muted-foreground">{globalIndex}</TableCell>
          <TableCell className="font-mono text-sm">{item.date}</TableCell>
          <TableCell>
            <div className="truncate max-w-[130px]">{vehicleText}</div>
            {item.vehicle && (
              <div className="text-xs text-muted-foreground truncate">{item.vehicle.model}</div>
            )}
          </TableCell>
          <TableCell className="text-center">
            <span className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${CATEGORY_COLORS[item.category] || 'bg-gray-100 text-gray-700'}`}>
              {item.category}
            </span>
          </TableCell>
          <TableCell className="truncate max-w-[180px]">{item.description}</TableCell>
          <TableCell className="text-right font-mono">{formatCurrency(item.amount)}</TableCell>
          <TableCell className="text-right font-mono">
            {item.mileage ? item.mileage.toLocaleString() : '-'}
          </TableCell>
          <TableCell className="text-sm text-muted-foreground truncate max-w-[120px]">
            {item.vendor || '-'}
          </TableCell>
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            <div className="flex items-center justify-center gap-1">
              <Button variant="ghost" size="icon" className="h-7 w-7" onClick={() => handleEdit(item)}>
                <Edit className="h-3.5 w-3.5" />
              </Button>
              <Button variant="ghost" size="icon" className="h-7 w-7 text-red-500" onClick={() => handleDeleteClick(item)}>
                <Trash2 className="h-3.5 w-3.5" />
              </Button>
            </div>
          </TableCell>
        </TableRow>
      );
    },
    [handleEdit, handleDeleteClick]
  );

  // 모바일 카드 렌더
  const renderMobileCard = useCallback(
    (
      item: VehicleMaintenance,
      _index: number,
      _globalIndex: number,
      isSelected: boolean,
      onToggle: () => void
    ) => {
      const vehicleText = item.vehicle
        ? `${item.vehicle.plateNumber} (${item.vehicle.model})`
        : '-';

      return (
        <MobileCard
          key={item.id}
          title={item.description}
          subtitle={`${item.date} · ${vehicleText}`}
          headerBadges={
            <span className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${CATEGORY_COLORS[item.category] || 'bg-gray-100 text-gray-700'}`}>
              {item.category}
            </span>
          }
          infoGrid={[
            <InfoField key="amount" label="금액" value={formatCurrency(item.amount)} />,
            <InfoField key="mileage" label="주행거리" value={item.mileage ? formatDistance(item.mileage) : '-'} />,
            <InfoField key="vendor" label="업체" value={item.vendor || '-'} />,
          ]}
          isSelected={isSelected}
          onToggleSelection={onToggle}
          onClick={() => handleEdit(item)}
        />
      );
    },
    [handleEdit]
  );

  return (
    <>
      <IntegratedListTemplateV2<VehicleMaintenance>
        title="정비이력"
        description="Vehicle Maintenance History"
        icon={Wrench}
        // 검색
        searchValue={search}
        onSearchChange={(v) => { setSearch(v); setCurrentPage(1); }}
        searchPlaceholder="내용, 업체 검색..."
        // 날짜 범위
        dateRangeSelector={{
          enabled: true,
          showPresets: true,
          presets: ['thisYear', 'lastMonth', 'thisMonth'],
          startDate,
          endDate,
          onStartDateChange: (v) => { setStartDate(v); setCurrentPage(1); },
          onEndDateChange: (v) => { setEndDate(v); setCurrentPage(1); },
        }}
        // 헤더 액션 (엑셀 다운로드)
        headerActions={(
          <Button variant="outline" size="sm" onClick={handleExcelDownload}>
            <Download className="mr-1 h-4 w-4" />
            엑셀 다운로드
          </Button>
        )}
        // 등록 버튼
        createButton={{ label: '비용 등록', onClick: handleCreate }}
        // 통계
        stats={stats}
        // 통합 필터 (PC: 인라인, 모바일: 바텀시트)
        filterConfig={filterConfig}
        filterValues={filterValues}
        onFilterChange={handleFilterChange}
        onFilterReset={handleFilterReset}
        filterTitle="비용 필터"
        // 컬럼
        tableColumns={visibleColumns}
        columnSettings={{
          columnWidths,
          onColumnResize: setColumnWidth,
          settingsPopover: (
            <ColumnSettingsPopover
              columns={allColumnsWithVisibility}
              onToggle={toggleColumnVisibility}
              onReset={resetSettings}
              hasHiddenColumns={hasHiddenColumns}
            />
          ),
        }}
        // 데이터
        data={data}
        selectedItems={selectedIds}
        onToggleSelection={toggleSelection}
        onToggleSelectAll={toggleSelectAll}
        getItemId={(item) => String(item.id)}
        // 렌더링
        renderTableRow={renderTableRow}
        renderMobileCard={renderMobileCard}
        // 페이지네이션
        pagination={{
          currentPage,
          totalPages,
          totalItems,
          itemsPerPage: PAGE_SIZE,
          onPageChange: setCurrentPage,
        }}
        isLoading={isLoading}
      />

      <MaintenanceFormDialog
        open={dialogOpen}
        onOpenChange={setDialogOpen}
        mode={dialogMode}
        maintenance={selectedItem}
        vehicles={vehicles}
        onSuccess={fetchData}
      />

      <DeleteConfirmDialog
        open={deleteOpen}
        onOpenChange={setDeleteOpen}
        description="이 비용을 삭제하시겠습니까?"
        loading={isDeleting}
        onConfirm={handleDeleteConfirm}
      />
    </>
  );
}
