'use client';

import { useState, useCallback, useMemo, useRef } from 'react';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Separator } from '@/components/ui/separator';
import { CurrencyInput } from '@/components/ui/currency-input';
import { DatePicker } from '@/components/ui/date-picker';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { SearchableSelectionModal } from '@/components/organisms/SearchableSelectionModal';
import { Save, Search, UserPlus } from 'lucide-react';
import { getEmployees } from '@/components/hr/EmployeeManagement/actions';
import type { Employee } from '@/components/hr/EmployeeManagement/types';
import { formatCurrency } from './types';

// ===== 기본값 상수 =====
const DEFAULT_ALLOWANCES = {
  positionAllowance: 0,
  overtimeAllowance: 0,
  mealAllowance: 150000,
  transportAllowance: 100000,
  otherAllowance: 0,
};

const DEFAULT_DEDUCTIONS = {
  nationalPension: 0,
  healthInsurance: 0,
  longTermCare: 0,
  employmentInsurance: 0,
  incomeTax: 0,
  localIncomeTax: 0,
  otherDeduction: 0,
};

// 기본급 기준 4대보험 + 세금 자동 계산
function calculateDefaultDeductions(baseSalary: number) {
  const nationalPension = Math.round(baseSalary * 0.045); // 국민연금 4.5%
  const healthInsurance = Math.round(baseSalary * 0.03545); // 건강보험 3.545%
  const longTermCare = Math.round(healthInsurance * 0.1281); // 장기요양 12.81% of 건강보험
  const employmentInsurance = Math.round(baseSalary * 0.009); // 고용보험 0.9%
  const totalIncome = baseSalary + DEFAULT_ALLOWANCES.mealAllowance + DEFAULT_ALLOWANCES.transportAllowance;
  const incomeTax = Math.round(totalIncome * 0.05); // 소득세 (간이세액 근사)
  const localIncomeTax = Math.round(incomeTax * 0.1); // 지방소득세 10% of 소득세

  return {
    nationalPension,
    healthInsurance,
    longTermCare,
    employmentInsurance,
    incomeTax,
    localIncomeTax,
    otherDeduction: 0,
  };
}

// ===== 행 컴포넌트 =====
function EditableRow({
  label,
  value,
  onChange,
  prefix,
}: {
  label: string;
  value: number;
  onChange: (value: number) => void;
  prefix?: string;
}) {
  return (
    <div className="flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-2">
      <span className="text-muted-foreground whitespace-nowrap text-xs sm:text-sm sm:w-24 sm:shrink-0">{label}</span>
      <div className="flex-1">
        <CurrencyInput
          value={value}
          onChange={(v) => onChange(v ?? 0)}
          className="w-full h-7 text-sm text-right"
        />
      </div>
    </div>
  );
}

// ===== Props =====
interface SalaryRegistrationDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSave: (data: {
    employeeId: number;
    employeeName: string;
    department: string;
    position: string;
    rank: string;
    year: number;
    month: number;
    baseSalary: number;
    paymentDate: string;
    allowances: Record<string, number>;
    deductions: Record<string, number>;
  }) => void;
}

// ===== 컴포넌트 =====
export function SalaryRegistrationDialog({
  open,
  onOpenChange,
  onSave,
}: SalaryRegistrationDialogProps) {
  // 사원 선택
  const [employeeSearchOpen, setEmployeeSearchOpen] = useState(false);
  const [selectedEmployee, setSelectedEmployee] = useState<Employee | null>(null);
  const searchOpenRef = useRef(false);

  // 급여 기본 정보
  const now = new Date();
  const [year, setYear] = useState(now.getFullYear());
  const [month, setMonth] = useState(now.getMonth() + 1);
  const [paymentDate, setPaymentDate] = useState('');
  const [baseSalary, setBaseSalary] = useState(0);

  // 수당
  const [allowances, setAllowances] = useState({ ...DEFAULT_ALLOWANCES });

  // 공제
  const [deductions, setDeductions] = useState({ ...DEFAULT_DEDUCTIONS });

  // 검색 모달 열기/닫기 (ref 동기화 - 닫힘 전파 방지를 위해 해제 지연)
  const handleSearchOpenChange = useCallback((isOpen: boolean) => {
    if (isOpen) {
      searchOpenRef.current = true;
    } else {
      setTimeout(() => { searchOpenRef.current = false; }, 300);
    }
    setEmployeeSearchOpen(isOpen);
  }, []);

  // 사원 선택 시 기본값 세팅
  const handleSelectEmployee = useCallback((employee: Employee) => {
    setSelectedEmployee(employee);
    handleSearchOpenChange(false);

    // 기본급 세팅 (연봉 / 12)
    const monthlySalary = employee.salary ? Math.round(employee.salary / 12) : 0;
    setBaseSalary(monthlySalary);

    // 기본 공제 자동 계산
    if (monthlySalary > 0) {
      setDeductions(calculateDefaultDeductions(monthlySalary));
    }
  }, []);

  // 사원 검색 fetch
  const handleFetchEmployees = useCallback(async (query: string) => {
    const result = await getEmployees({
      q: query || undefined,
      status: 'active',
      per_page: 50,
    });
    return result.data || [];
  }, []);

  // 검색어 유효성
  const isValidSearch = useCallback((query: string) => {
    if (!query || !query.trim()) return false;
    return /[a-zA-Z가-힣ㄱ-ㅎㅏ-ㅣ0-9]/.test(query);
  }, []);

  // 수당 변경
  const handleAllowanceChange = useCallback((field: string, value: number) => {
    setAllowances(prev => ({ ...prev, [field]: value }));
  }, []);

  // 공제 변경
  const handleDeductionChange = useCallback((field: string, value: number) => {
    setDeductions(prev => ({ ...prev, [field]: value }));
  }, []);

  // 합계 계산
  const totalAllowance = useMemo(() =>
    Object.values(allowances).reduce((sum, v) => sum + v, 0),
    [allowances]
  );

  const totalDeduction = useMemo(() =>
    Object.values(deductions).reduce((sum, v) => sum + v, 0),
    [deductions]
  );

  const netPayment = useMemo(() =>
    baseSalary + totalAllowance - totalDeduction,
    [baseSalary, totalAllowance, totalDeduction]
  );

  // 저장 가능 여부
  const canSave = selectedEmployee && baseSalary > 0 && year > 0 && month > 0;

  // 저장
  const handleSave = useCallback(() => {
    if (!selectedEmployee || !canSave) return;

    const dept = selectedEmployee.departmentPositions?.[0];

    onSave({
      employeeId: selectedEmployee.userId || parseInt(selectedEmployee.id, 10),
      employeeName: selectedEmployee.name,
      department: dept?.departmentName || '-',
      position: dept?.positionName || '-',
      rank: selectedEmployee.rank || '-',
      year,
      month,
      baseSalary,
      paymentDate,
      allowances: {
        position_allowance: allowances.positionAllowance,
        overtime_allowance: allowances.overtimeAllowance,
        meal_allowance: allowances.mealAllowance,
        transport_allowance: allowances.transportAllowance,
        other_allowance: allowances.otherAllowance,
      },
      deductions: {
        national_pension: deductions.nationalPension,
        health_insurance: deductions.healthInsurance,
        long_term_care: deductions.longTermCare,
        employment_insurance: deductions.employmentInsurance,
        income_tax: deductions.incomeTax,
        local_income_tax: deductions.localIncomeTax,
        other_deduction: deductions.otherDeduction,
      },
    });
  }, [selectedEmployee, canSave, year, month, baseSalary, paymentDate, allowances, deductions, onSave]);

  // 다이얼로그 닫힐 때 초기화 (검색 모달 닫힘 전파 방지)
  const handleOpenChange = useCallback((isOpen: boolean) => {
    if (!isOpen && searchOpenRef.current) return;
    if (!isOpen) {
      setSelectedEmployee(null);
      setBaseSalary(0);
      setPaymentDate('');
      setAllowances({ ...DEFAULT_ALLOWANCES });
      setDeductions({ ...DEFAULT_DEDUCTIONS });
    }
    onOpenChange(isOpen);
  }, [onOpenChange]);

  // 년도 옵션
  const yearOptions = useMemo(() => {
    const currentYear = new Date().getFullYear();
    return Array.from({ length: 3 }, (_, i) => currentYear - 1 + i);
  }, []);

  // 월 옵션
  const monthOptions = useMemo(() =>
    Array.from({ length: 12 }, (_, i) => i + 1),
    []
  );

  return (
    <>
      <Dialog open={open} onOpenChange={handleOpenChange}>
        <DialogContent className="sm:max-w-[700px] max-h-[90vh] overflow-y-auto p-4 sm:p-6">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <UserPlus className="h-5 w-5" />
              급여 등록
            </DialogTitle>
          </DialogHeader>

          <div className="space-y-6">
            {/* 사원 선택 */}
            <div className="bg-muted/50 rounded-lg p-3 sm:p-4">
              <h3 className="font-semibold mb-3">기본 정보</h3>

              {/* 사원 선택 버튼 */}
              {!selectedEmployee ? (
                <Button
                  variant="outline"
                  className="w-full h-12 border-dashed"
                  onClick={() => handleSearchOpenChange(true)}
                >
                  <Search className="h-4 w-4 mr-2" />
                  사원 검색 (클릭하여 선택)
                </Button>
              ) : (
                <div className="space-y-3">
                  <div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
                    <div>
                      <span className="text-muted-foreground">사번</span>
                      <p className="font-medium">{selectedEmployee.employeeCode || selectedEmployee.id}</p>
                    </div>
                    <div>
                      <span className="text-muted-foreground">이름</span>
                      <p className="font-medium">{selectedEmployee.name}</p>
                    </div>
                    <div>
                      <span className="text-muted-foreground">부서</span>
                      <p className="font-medium">
                        {selectedEmployee.departmentPositions?.[0]?.departmentName || '-'}
                      </p>
                    </div>
                    <div>
                      <span className="text-muted-foreground">직급</span>
                      <p className="font-medium">{selectedEmployee.rank || '-'}</p>
                    </div>
                    <div>
                      <span className="text-muted-foreground">직책</span>
                      <p className="font-medium">
                        {selectedEmployee.departmentPositions?.[0]?.positionName || '-'}
                      </p>
                    </div>
                  </div>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="text-xs text-muted-foreground"
                    onClick={() => handleSearchOpenChange(true)}
                  >
                    다른 사원 선택
                  </Button>
                </div>
              )}

              {/* 지급월 / 지급일 */}
              <div className="grid grid-cols-2 sm:grid-cols-3 gap-3 mt-4">
                <div>
                  <span className="text-sm text-muted-foreground block mb-1">년도</span>
                  <Select value={String(year)} onValueChange={(v) => setYear(Number(v))}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {yearOptions.map(y => (
                        <SelectItem key={y} value={String(y)}>{y}년</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div>
                  <span className="text-sm text-muted-foreground block mb-1">월</span>
                  <Select value={String(month)} onValueChange={(v) => setMonth(Number(v))}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {monthOptions.map(m => (
                        <SelectItem key={m} value={String(m)}>{m}월</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="col-span-2 sm:col-span-1">
                  <span className="text-sm text-muted-foreground block mb-1">지급일</span>
                  <DatePicker
                    value={paymentDate}
                    onChange={setPaymentDate}
                    placeholder="지급일 선택"
                  />
                </div>
              </div>

              {/* 기본급 */}
              <div className="mt-4">
                <span className="text-sm text-muted-foreground block mb-1">기본급 (월)</span>
                <CurrencyInput
                  value={baseSalary}
                  onChange={(v) => {
                    const newSalary = v ?? 0;
                    setBaseSalary(newSalary);
                    if (newSalary > 0) {
                      setDeductions(calculateDefaultDeductions(newSalary));
                    }
                  }}
                  className="w-full"
                />
                {selectedEmployee?.salary && (
                  <span className="text-xs text-muted-foreground mt-1 block">
                    연봉 {formatCurrency(selectedEmployee.salary)}원 기준
                  </span>
                )}
              </div>
            </div>

            {/* 수당 / 공제 */}
            <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
              {/* 수당 내역 */}
              <div className="border rounded-lg p-3 sm:p-4 flex flex-col">
                <h3 className="font-semibold mb-3 text-blue-600">수당 내역</h3>
                <div className="space-y-2 text-sm flex-1">
                  <EditableRow
                    label="직책수당"
                    value={allowances.positionAllowance}
                    onChange={(v) => handleAllowanceChange('positionAllowance', v)}
                  />
                  <EditableRow
                    label="초과근무수당"
                    value={allowances.overtimeAllowance}
                    onChange={(v) => handleAllowanceChange('overtimeAllowance', v)}
                  />
                  <EditableRow
                    label="식대"
                    value={allowances.mealAllowance}
                    onChange={(v) => handleAllowanceChange('mealAllowance', v)}
                  />
                  <EditableRow
                    label="교통비"
                    value={allowances.transportAllowance}
                    onChange={(v) => handleAllowanceChange('transportAllowance', v)}
                  />
                  <EditableRow
                    label="기타수당"
                    value={allowances.otherAllowance}
                    onChange={(v) => handleAllowanceChange('otherAllowance', v)}
                  />
                </div>
                <div className="mt-auto pt-2">
                  <Separator />
                  <div className="flex items-center gap-2 font-semibold text-blue-600 mt-2">
                    <span className="w-20 sm:w-24 shrink-0">수당 합계</span>
                    <span className="flex-1 text-right">{formatCurrency(totalAllowance)}원</span>
                  </div>
                </div>
              </div>

              {/* 공제 내역 */}
              <div className="border rounded-lg p-3 sm:p-4 flex flex-col">
                <h3 className="font-semibold mb-3 text-red-600">공제 내역</h3>
                <div className="space-y-2 text-sm flex-1">
                  <EditableRow
                    label="국민연금"
                    value={deductions.nationalPension}
                    onChange={(v) => handleDeductionChange('nationalPension', v)}
                  />
                  <EditableRow
                    label="건강보험"
                    value={deductions.healthInsurance}
                    onChange={(v) => handleDeductionChange('healthInsurance', v)}
                  />
                  <EditableRow
                    label="장기요양보험"
                    value={deductions.longTermCare}
                    onChange={(v) => handleDeductionChange('longTermCare', v)}
                  />
                  <EditableRow
                    label="고용보험"
                    value={deductions.employmentInsurance}
                    onChange={(v) => handleDeductionChange('employmentInsurance', v)}
                  />
                  <Separator />
                  <EditableRow
                    label="소득세"
                    value={deductions.incomeTax}
                    onChange={(v) => handleDeductionChange('incomeTax', v)}
                  />
                  <EditableRow
                    label="지방소득세"
                    value={deductions.localIncomeTax}
                    onChange={(v) => handleDeductionChange('localIncomeTax', v)}
                  />
                  <EditableRow
                    label="기타공제"
                    value={deductions.otherDeduction}
                    onChange={(v) => handleDeductionChange('otherDeduction', v)}
                  />
                </div>
                <div className="mt-auto pt-2">
                  <Separator />
                  <div className="flex items-center gap-2 font-semibold text-red-600 mt-2">
                    <span className="w-20 sm:w-24 shrink-0">공제 합계</span>
                    <span className="flex-1 text-right">-{formatCurrency(totalDeduction)}원</span>
                  </div>
                </div>
              </div>
            </div>

            {/* 합계 */}
            <div className="bg-primary/5 border-2 border-primary/20 rounded-lg p-3 sm:p-4">
              <div className="grid grid-cols-1 sm:grid-cols-3 gap-3 sm:gap-4 text-center">
                <div>
                  <span className="text-xs sm:text-sm text-muted-foreground block">급여 총액</span>
                  <span className="text-sm sm:text-lg font-semibold text-blue-600">
                    {formatCurrency(baseSalary + totalAllowance)}원
                  </span>
                </div>
                <div>
                  <span className="text-xs sm:text-sm text-muted-foreground block">공제 총액</span>
                  <span className="text-sm sm:text-lg font-semibold text-red-600">
                    -{formatCurrency(totalDeduction)}원
                  </span>
                </div>
                <div>
                  <span className="text-xs sm:text-sm text-muted-foreground block">실지급액</span>
                  <span className="text-base sm:text-xl font-bold text-primary">
                    {formatCurrency(netPayment)}원
                  </span>
                </div>
              </div>
            </div>
          </div>

          <DialogFooter className="mt-6">
            <Button variant="outline" onClick={() => handleOpenChange(false)}>
              취소
            </Button>
            <Button onClick={handleSave} disabled={!canSave} className="gap-2">
              <Save className="h-4 w-4" />
              등록
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 사원 검색 모달 */}
      <SearchableSelectionModal<Employee>
        open={employeeSearchOpen}
        onOpenChange={handleSearchOpenChange}
        title="사원 검색"
        searchPlaceholder="사원명, 사원코드 검색..."
        fetchData={handleFetchEmployees}
        keyExtractor={(emp) => emp.id}
        validateSearch={isValidSearch}
        invalidSearchMessage="한글, 영문 또는 숫자 1자 이상 입력하세요"
        emptyQueryMessage="사원명 또는 사원코드를 입력하세요"
        loadingMessage="사원 검색 중..."
        dialogClassName="sm:max-w-[500px]"
        infoText={(items, isLoading) =>
          !isLoading ? (
            <span className="text-xs text-gray-400 text-right block">
              총 {items.length}명
            </span>
          ) : null
        }
        mode="single"
        onSelect={handleSelectEmployee}
        renderItem={(employee) => (
          <div className="p-3 hover:bg-blue-50 transition-colors">
            <div className="flex items-center justify-between">
              <div>
                <span className="font-semibold text-gray-900">{employee.name}</span>
                {employee.employeeCode && (
                  <span className="text-xs text-gray-400 ml-2">({employee.employeeCode})</span>
                )}
              </div>
              {employee.rank && (
                <span className="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded">
                  {employee.rank}
                </span>
              )}
            </div>
            {employee.departmentPositions.length > 0 && (
              <p className="text-sm text-gray-600 mt-1">
                {employee.departmentPositions
                  .map(dp => `${dp.departmentName} / ${dp.positionName}`)
                  .join(', ')}
              </p>
            )}
            {employee.salary && (
              <p className="text-xs text-gray-400 mt-1">
                연봉: {Number(employee.salary).toLocaleString()}원
              </p>
            )}
          </div>
        )}
      />
    </>
  );
}
