'use client';

import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
import {
  Download,
  DollarSign,
  Check,
  Clock,
  Pencil,
  Banknote,
  Briefcase,
  Timer,
  Gift,
  MinusCircle,
  Loader2,
  Search,
} from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Checkbox } from '@/components/ui/checkbox';
import { Badge } from '@/components/ui/badge';
import { TableRow, TableCell } from '@/components/ui/table';
import {
  UniversalListPage,
  type UniversalListConfig,
  type StatCard,
  type FilterFieldConfig,
  type FilterValues,
} from '@/components/templates/UniversalListPage';
import { ListMobileCard, InfoField } from '@/components/organisms/MobileCard';
import { SalaryDetailDialog } from './SalaryDetailDialog';
import {
  getSalaries,
  getSalary,
  bulkUpdateSalaryStatus,
  updateSalaryStatus,
  updateSalary,
} from './actions';
import type {
  SalaryRecord,
  SalaryDetail,
  PaymentStatus,
  SortOption,
} from './types';
import {
  PAYMENT_STATUS_LABELS,
  PAYMENT_STATUS_COLORS,
  SORT_OPTIONS,
  formatCurrency,
} from './types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';

export function SalaryManagement() {
  // ===== 상태 관리 =====
  const [searchQuery, setSearchQuery] = useState('');
  const [sortOption, setSortOption] = useState<SortOption>('rank');
  const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 20;

  // 날짜 범위 상태
  const [startDate, setStartDate] = useState('2025-12-01');
  const [endDate, setEndDate] = useState('2025-12-31');

  // 다이얼로그 상태
  const [detailDialogOpen, setDetailDialogOpen] = useState(false);
  const [selectedSalaryDetail, setSelectedSalaryDetail] = useState<SalaryDetail | null>(null);
  const [selectedSalaryId, setSelectedSalaryId] = useState<string | null>(null);

  // 데이터 상태
  const [salaryData, setSalaryData] = useState<SalaryRecord[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const isInitialLoadDone = useRef(false);
  const [isActionLoading, setIsActionLoading] = useState(false);
  const [totalCount, setTotalCount] = useState(0);
  const [totalPages, setTotalPages] = useState(1);

  // ===== 데이터 로드 =====
  const loadSalaries = useCallback(async () => {
    if (!isInitialLoadDone.current) {
      setIsLoading(true);
    }
    try {
      const result = await getSalaries({
        search: searchQuery || undefined,
        start_date: startDate || undefined,
        end_date: endDate || undefined,
        page: currentPage,
        per_page: itemsPerPage,
      });

      if (result.success && result.data) {
        setSalaryData(result.data);
        setTotalCount(result.pagination?.total || result.data.length);
        setTotalPages(result.pagination?.lastPage || 1);
      } else {
        toast.error(result.error || '급여 목록을 불러오는데 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('loadSalaries error:', error);
      toast.error('급여 목록을 불러오는데 실패했습니다.');
    } finally {
      setIsLoading(false);
      isInitialLoadDone.current = true;
    }
  }, [searchQuery, startDate, endDate, currentPage, itemsPerPage]);

  // 초기 데이터 로드 및 검색/필터 변경 시 재로드
  useEffect(() => {
    loadSalaries();
  }, [loadSalaries]);

  // ===== 체크박스 핸들러 =====
  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 === salaryData.length && salaryData.length > 0) {
      setSelectedItems(new Set());
    } else {
      setSelectedItems(new Set(salaryData.map(item => item.id)));
    }
  }, [selectedItems.size, salaryData]);

  // ===== 지급완료 핸들러 =====
  const handleMarkCompleted = useCallback(async () => {
    if (selectedItems.size === 0) return;

    setIsActionLoading(true);
    try {
      const result = await bulkUpdateSalaryStatus(
        Array.from(selectedItems),
        'completed'
      );

      if (result.success) {
        toast.success(`${result.updatedCount || selectedItems.size}건이 지급완료 처리되었습니다.`);
        setSelectedItems(new Set());
        await loadSalaries();
      } else {
        toast.error(result.error || '상태 변경에 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('handleMarkCompleted error:', error);
      toast.error('상태 변경에 실패했습니다.');
    } finally {
      setIsActionLoading(false);
    }
  }, [selectedItems, loadSalaries]);

  // ===== 지급예정 핸들러 =====
  const handleMarkScheduled = useCallback(async () => {
    if (selectedItems.size === 0) return;

    setIsActionLoading(true);
    try {
      const result = await bulkUpdateSalaryStatus(
        Array.from(selectedItems),
        'scheduled'
      );

      if (result.success) {
        toast.success(`${result.updatedCount || selectedItems.size}건이 지급예정 처리되었습니다.`);
        setSelectedItems(new Set());
        await loadSalaries();
      } else {
        toast.error(result.error || '상태 변경에 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('handleMarkScheduled error:', error);
      toast.error('상태 변경에 실패했습니다.');
    } finally {
      setIsActionLoading(false);
    }
  }, [selectedItems, loadSalaries]);

  // ===== 상세보기 핸들러 =====
  const handleViewDetail = useCallback(async (record: SalaryRecord) => {
    setSelectedSalaryId(record.id);
    setIsActionLoading(true);
    try {
      const result = await getSalary(record.id);
      if (result.success && result.data) {
        setSelectedSalaryDetail(result.data);
        setDetailDialogOpen(true);
      } else {
        toast.error(result.error || '급여 상세 정보를 불러오는데 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('handleViewDetail error:', error);
      toast.error('급여 상세 정보를 불러오는데 실패했습니다.');
    } finally {
      setIsActionLoading(false);
    }
  }, []);

  // ===== 급여 상세 저장 핸들러 =====
  const handleSaveDetail = useCallback(async (
    updatedDetail: SalaryDetail,
    allowanceDetails?: Record<string, number>
  ) => {
    if (!selectedSalaryId) return;

    setIsActionLoading(true);
    try {
      // 수당 정보가 변경된 경우 updateSalary API 호출
      if (allowanceDetails) {
        const result = await updateSalary(selectedSalaryId, {
          allowance_details: allowanceDetails,
          status: updatedDetail.status,
        });
        if (result.success) {
          toast.success('급여 정보가 저장되었습니다.');
          setDetailDialogOpen(false);
          await loadSalaries();
        } else {
          toast.error(result.error || '저장에 실패했습니다.');
        }
      } else {
        // 상태만 변경된 경우 기존 API 호출
        const result = await updateSalaryStatus(selectedSalaryId, updatedDetail.status);
        if (result.success) {
          toast.success('급여 정보가 저장되었습니다.');
          setDetailDialogOpen(false);
          await loadSalaries();
        } else {
          toast.error(result.error || '저장에 실패했습니다.');
        }
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('handleSaveDetail error:', error);
      toast.error('저장에 실패했습니다.');
    } finally {
      setIsActionLoading(false);
    }
  }, [selectedSalaryId, loadSalaries]);

  // ===== 지급항목 추가 핸들러 =====
  const handleAddPaymentItem = useCallback(() => {
    // TODO: 지급항목 추가 다이얼로그 또는 로직 구현
    toast.info('지급항목 추가 기능은 준비 중입니다.');
  }, []);

  // ===== 통계 카드 (총 실지급액, 총 기본급, 총 수당, 초과근무, 상여, 총공제) =====
  const statCards: StatCard[] = useMemo(() => {
    const totalNetPayment = salaryData.reduce((sum, s) => sum + s.netPayment, 0);
    const totalBaseSalary = salaryData.reduce((sum, s) => sum + s.baseSalary, 0);
    const totalAllowance = salaryData.reduce((sum, s) => sum + s.allowance, 0);
    const totalOvertime = salaryData.reduce((sum, s) => sum + s.overtime, 0);
    const totalBonus = salaryData.reduce((sum, s) => sum + s.bonus, 0);
    const totalDeduction = salaryData.reduce((sum, s) => sum + s.deduction, 0);

    return [
      {
        label: '총 실지급액',
        value: `${formatCurrency(totalNetPayment)}원`,
        icon: DollarSign,
        iconColor: 'text-green-500',
      },
      {
        label: '총 기본급',
        value: `${formatCurrency(totalBaseSalary)}원`,
        icon: Banknote,
        iconColor: 'text-blue-500',
      },
      {
        label: '총 수당',
        value: `${formatCurrency(totalAllowance)}원`,
        icon: Briefcase,
        iconColor: 'text-purple-500',
      },
      {
        label: '초과근무',
        value: `${formatCurrency(totalOvertime)}원`,
        icon: Timer,
        iconColor: 'text-orange-500',
      },
      {
        label: '상여',
        value: `${formatCurrency(totalBonus)}원`,
        icon: Gift,
        iconColor: 'text-pink-500',
      },
      {
        label: '총 공제',
        value: `${formatCurrency(totalDeduction)}원`,
        icon: MinusCircle,
        iconColor: 'text-red-500',
      },
    ];
  }, [salaryData]);

  // ===== 테이블 컬럼 (부서, 직책, 이름, 직급, 기본급, 수당, 초과근무, 상여, 공제, 실지급액, 일자, 상태, 작업) =====
  const tableColumns = useMemo(() => [
    { key: 'department', label: '부서' },
    { key: 'position', label: '직책' },
    { key: 'name', label: '이름' },
    { key: 'rank', label: '직급' },
    { key: 'baseSalary', label: '기본급', className: 'text-right' },
    { key: 'allowance', label: '수당', className: 'text-right' },
    { key: 'overtime', label: '초과근무', className: 'text-right' },
    { key: 'bonus', label: '상여', className: 'text-right' },
    { key: 'deduction', label: '공제', className: 'text-right' },
    { key: 'netPayment', label: '실지급액', className: 'text-right' },
    { key: 'paymentDate', label: '일자', className: 'text-center' },
    { key: 'status', label: '상태', className: 'text-center' },
    { key: 'action', label: '작업', className: 'text-center w-[80px]' },
  ], []);

  // ===== filterConfig 기반 통합 필터 시스템 =====
  const filterConfig: FilterFieldConfig[] = useMemo(() => [
    {
      key: 'sort',
      label: '정렬',
      type: 'single',
      options: Object.entries(SORT_OPTIONS).map(([value, label]) => ({
        value,
        label,
      })),
    },
  ], []);

  const filterValues: FilterValues = useMemo(() => ({
    sort: sortOption,
  }), [sortOption]);

  const handleFilterChange = useCallback((key: string, value: string | string[]) => {
    switch (key) {
      case 'sort':
        setSortOption(value as SortOption);
        break;
    }
    setCurrentPage(1);
  }, []);

  const handleFilterReset = useCallback(() => {
    setSortOption('rank');
    setCurrentPage(1);
  }, []);

  // ===== UniversalListPage 설정 =====
  const salaryConfig: UniversalListConfig<SalaryRecord> = useMemo(() => ({
    title: '급여관리',
    description: '직원들의 급여 현황을 관리합니다',
    icon: DollarSign,
    basePath: '/hr/salary-management',

    idField: 'id',

    actions: {
      getList: async () => ({
        success: true,
        data: salaryData,
        totalCount: totalCount,
        totalPages: totalPages,
      }),
    },

    columns: tableColumns,

    filterConfig: filterConfig,
    initialFilters: filterValues,
    filterTitle: '급여 필터',

    computeStats: () => statCards,

    searchPlaceholder: '이름, 부서 검색...',

    itemsPerPage: itemsPerPage,

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

    // 날짜 범위 선택 (DateRangeSelector 사용)
    dateRangeSelector: {
      enabled: true,
      showPresets: false,
      startDate,
      endDate,
      onStartDateChange: setStartDate,
      onEndDateChange: setEndDate,
    },

    headerActions: ({ selectedItems: selected }) => (
      <div className="flex items-center gap-2 flex-wrap">
        {/* 지급완료/지급예정 버튼 - 선택된 항목이 있을 때만 표시 */}
        {selected.size > 0 && (
          <>
            <Button
              variant="default"
              onClick={handleMarkCompleted}
              disabled={isActionLoading}
            >
              {isActionLoading ? (
                <Loader2 className="h-4 w-4 mr-2 animate-spin" />
              ) : (
                <Check className="h-4 w-4 mr-2" />
              )}
              지급완료
            </Button>
            <Button
              variant="outline"
              onClick={handleMarkScheduled}
              disabled={isActionLoading}
            >
              {isActionLoading ? (
                <Loader2 className="h-4 w-4 mr-2 animate-spin" />
              ) : (
                <Clock className="h-4 w-4 mr-2" />
              )}
              지급예정
            </Button>
          </>
        )}

        <Button variant="outline" onClick={() => toast.info('엑셀 다운로드 기능은 준비 중입니다.')}>
          <Download className="h-4 w-4 mr-2" />
          엑셀 다운로드
        </Button>
      </div>
    ),

    renderTableRow: (item, index, globalIndex, handlers) => {
      const { isSelected, onToggle } = handlers;

      return (
        <TableRow key={item.id} className="hover:bg-muted/50">
          <TableCell className="text-center">
            <Checkbox checked={isSelected} onCheckedChange={onToggle} />
          </TableCell>
          <TableCell>{item.department}</TableCell>
          <TableCell>{item.position}</TableCell>
          <TableCell className="font-medium">{item.employeeName}</TableCell>
          <TableCell>{item.rank}</TableCell>
          <TableCell className="text-right">{formatCurrency(item.baseSalary)}원</TableCell>
          <TableCell className="text-right">{formatCurrency(item.allowance)}원</TableCell>
          <TableCell className="text-right">{formatCurrency(item.overtime)}원</TableCell>
          <TableCell className="text-right">{formatCurrency(item.bonus)}원</TableCell>
          <TableCell className="text-right text-red-600">-{formatCurrency(item.deduction)}원</TableCell>
          <TableCell className="text-right font-medium text-green-600">{formatCurrency(item.netPayment)}원</TableCell>
          <TableCell className="text-center">{item.paymentDate}</TableCell>
          <TableCell className="text-center">
            <Badge className={PAYMENT_STATUS_COLORS[item.status]}>
              {PAYMENT_STATUS_LABELS[item.status]}
            </Badge>
          </TableCell>
          <TableCell className="text-center">
            <Button
              variant="ghost"
              size="sm"
              onClick={() => handleViewDetail(item)}
              title="수정"
              disabled={isActionLoading}
            >
              <Pencil className="h-4 w-4" />
            </Button>
          </TableCell>
        </TableRow>
      );
    },

    renderMobileCard: (item, index, globalIndex, handlers) => {
      const { isSelected, onToggle } = handlers;

      return (
        <ListMobileCard
          id={item.id}
          title={item.employeeName}
          headerBadges={
            <Badge className={PAYMENT_STATUS_COLORS[item.status]}>
              {PAYMENT_STATUS_LABELS[item.status]}
            </Badge>
          }
          isSelected={isSelected}
          onToggleSelection={onToggle}
          infoGrid={
            <div className="grid grid-cols-2 gap-3">
              <InfoField label="부서" value={item.department} />
              <InfoField label="직급" value={item.rank} />
              <InfoField label="기본급" value={`${formatCurrency(item.baseSalary)}원`} />
              <InfoField label="수당" value={`${formatCurrency(item.allowance)}원`} />
              <InfoField label="초과근무" value={`${formatCurrency(item.overtime)}원`} />
              <InfoField label="상여" value={`${formatCurrency(item.bonus)}원`} />
              <InfoField label="공제" value={`-${formatCurrency(item.deduction)}원`} />
              <InfoField label="실지급액" value={`${formatCurrency(item.netPayment)}원`} />
              <InfoField label="지급일" value={item.paymentDate} />
            </div>
          }
          actions={
            <Button
              variant="outline"
              size="sm"
              className="w-full"
              onClick={() => handleViewDetail(item)}
              disabled={isActionLoading}
            >
              <Pencil className="h-4 w-4 mr-2" />
              수정
            </Button>
          }
        />
      );
    },

    renderDialogs: () => (
      <SalaryDetailDialog
        open={detailDialogOpen}
        onOpenChange={setDetailDialogOpen}
        salaryDetail={selectedSalaryDetail}
        onSave={handleSaveDetail}
        onAddPaymentItem={handleAddPaymentItem}
      />
    ),
  }), [
    salaryData,
    totalCount,
    totalPages,
    tableColumns,
    filterConfig,
    filterValues,
    statCards,
    startDate,
    endDate,
    handleMarkCompleted,
    handleMarkScheduled,
    isActionLoading,
    handleViewDetail,
    detailDialogOpen,
    selectedSalaryDetail,
    handleSaveDetail,
    handleAddPaymentItem,
  ]);

  return (
    <UniversalListPage<SalaryRecord>
      config={salaryConfig}
      initialData={salaryData}
      initialTotalCount={totalCount}
      externalPagination={{
        currentPage,
        totalPages,
        totalItems: totalCount,
        itemsPerPage,
        onPageChange: setCurrentPage,
      }}
      externalSelection={{
        selectedItems,
        onToggleSelection: toggleSelection,
        onToggleSelectAll: toggleSelectAll,
        getItemId: (item) => item.id,
      }}
      onSearchChange={setSearchQuery}
      externalIsLoading={isLoading}
    />
  );
}