'use client';

import { useState, useEffect, useCallback } from 'react';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { Award, Plus, GripVertical, Edit, Trash2, Loader2 } from 'lucide-react';
import { ReorderButtons } from '@/components/molecules';
import { ContentSkeleton } from '@/components/ui/skeleton';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Card, CardContent } from '@/components/ui/card';
import { RankDialog } from './RankDialog';
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
import { useDeleteDialog } from '@/hooks/useDeleteDialog';
import { toast } from 'sonner';
import type { Rank } from './types';
import {
  getRanks,
  createRank,
  updateRank,
  deleteRank,
  reorderRanks,
} from './actions';
import { isNextRedirectError } from '@/lib/utils/redirect-error';

export function RankManagement() {
  // 직급 데이터
  const [ranks, setRanks] = useState<Rank[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isSubmitting, setIsSubmitting] = useState(false);

  // 입력 필드
  const [newRankName, setNewRankName] = useState('');

  // 다이얼로그 상태
  const [dialogOpen, setDialogOpen] = useState(false);
  const [dialogMode, setDialogMode] = useState<'add' | 'edit'>('add');
  const [selectedRank, setSelectedRank] = useState<Rank | undefined>();

  // 삭제 확인 다이얼로그
  const deleteDialog = useDeleteDialog({
    onDelete: async (id) => {
      const numId = Number(id);
      const result = await deleteRank(numId);
      if (result.success) {
        setRanks(prev => prev.filter(r => r.id !== numId));
      }
      return result;
    },
    entityName: '직급',
  });

  // 드래그 상태
  const [draggedItem, setDraggedItem] = useState<number | null>(null);

  // 데이터 로드
  const loadRanks = useCallback(async () => {
    try {
      setIsLoading(true);
      const result = await getRanks();
      if (result.success && result.data) {
        setRanks(result.data);
      } else {
        toast.error(result.error || '직급 목록을 불러오는데 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('직급 목록 조회 실패:', error);
      toast.error('직급 목록을 불러오는데 실패했습니다.');
    } finally {
      setIsLoading(false);
    }
  }, []);

  // 초기 데이터 로드
  useEffect(() => {
    loadRanks();
  }, [loadRanks]);

  // 직급 추가 (입력 필드에서 직접)
  const handleQuickAdd = async () => {
    if (!newRankName.trim() || isSubmitting) return;

    try {
      setIsSubmitting(true);
      const result = await createRank({ name: newRankName.trim() });
      if (result.success && result.data) {
        setRanks(prev => [...prev, result.data!]);
        setNewRankName('');
        toast.success('직급이 추가되었습니다.');
      } else {
        toast.error(result.error || '직급 추가에 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('직급 추가 실패:', error);
      toast.error('직급 추가에 실패했습니다.');
    } finally {
      setIsSubmitting(false);
    }
  };

  // 직급 수정 다이얼로그 열기
  const handleEdit = (rank: Rank) => {
    setSelectedRank(rank);
    setDialogMode('edit');
    setDialogOpen(true);
  };

  // 다이얼로그 제출
  const handleDialogSubmit = async (name: string) => {
    if (dialogMode === 'edit' && selectedRank) {
      try {
        setIsSubmitting(true);
        const result = await updateRank(selectedRank.id, { name });
        if (result.success) {
          setRanks(prev => prev.map(r =>
            r.id === selectedRank.id ? { ...r, name } : r
          ));
          toast.success('직급이 수정되었습니다.');
        } else {
          toast.error(result.error || '직급 수정에 실패했습니다.');
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('직급 수정 실패:', error);
        toast.error('직급 수정에 실패했습니다.');
      } finally {
        setIsSubmitting(false);
      }
    }
    setDialogOpen(false);
  };

  // 드래그 시작
  const handleDragStart = (e: React.DragEvent, index: number) => {
    setDraggedItem(index);
    e.dataTransfer.effectAllowed = 'move';
  };

  // 드래그 종료 - 서버에 순서 저장
  const handleDragEnd = async () => {
    if (draggedItem === null) return;

    setDraggedItem(null);

    // 순서 변경 API 호출
    try {
      const items = ranks.map((rank, idx) => ({
        id: rank.id,
        sort_order: idx + 1,
      }));
      const result = await reorderRanks(items);
      if (result.success) {
        toast.success('순서가 변경되었습니다.');
      } else {
        toast.error(result.error || '순서 변경에 실패했습니다.');
        loadRanks();
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('순서 변경 실패:', error);
      toast.error('순서 변경에 실패했습니다.');
      // 실패시 원래 순서로 복구
      loadRanks();
    }
  };

  // 드래그 오버
  const handleDragOver = (e: React.DragEvent, index: number) => {
    e.preventDefault();
    if (draggedItem === null || draggedItem === index) return;

    const newRanks = [...ranks];
    const draggedRank = newRanks[draggedItem];
    newRanks.splice(draggedItem, 1);
    newRanks.splice(index, 0, draggedRank);

    // 순서 업데이트 (로컬)
    const reorderedRanks = newRanks.map((rank, idx) => ({
      ...rank,
      order: idx + 1
    }));

    setRanks(reorderedRanks);
    setDraggedItem(index);
  };

  // 화살표 버튼으로 순서 변경
  const handleMoveItem = async (fromIndex: number, toIndex: number) => {
    const newRanks = [...ranks];
    const [moved] = newRanks.splice(fromIndex, 1);
    newRanks.splice(toIndex, 0, moved);
    const reordered = newRanks.map((rank, idx) => ({ ...rank, order: idx + 1 }));
    setRanks(reordered);

    try {
      const items = reordered.map((rank, idx) => ({
        id: rank.id,
        sort_order: idx + 1,
      }));
      const result = await reorderRanks(items);
      if (result.success) {
        toast.success('순서가 변경되었습니다.');
      } else {
        toast.error(result.error || '순서 변경에 실패했습니다.');
        loadRanks();
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      toast.error('순서 변경에 실패했습니다.');
      loadRanks();
    }
  };

  // 키보드로 추가 (한글 IME 조합 중에는 무시)
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.nativeEvent.isComposing) {
      handleQuickAdd();
    }
  };

  return (
    <PageLayout>
      <PageHeader
        title="직급관리"
        description="사원의 직급을 관리합니다. 화살표 버튼 또는 드래그하여 순서를 변경할 수 있습니다."
        icon={Award}
      />

      <div className="space-y-4">
        {/* 직급 추가 입력 영역 */}
        <Card>
          <CardContent className="p-4">
            <div className="flex gap-2">
              <Input
                value={newRankName}
                onChange={(e) => setNewRankName(e.target.value)}
                onKeyDown={handleKeyDown}
                placeholder="직급명을 입력하세요"
                className="flex-1"
                disabled={isSubmitting}
              />
              <Button
                onClick={handleQuickAdd}
                disabled={!newRankName.trim() || isSubmitting}
              >
                {isSubmitting ? (
                  <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                ) : (
                  <Plus className="h-4 w-4 mr-2" />
                )}
                추가
              </Button>
            </div>
          </CardContent>
        </Card>

        {/* 직급 목록 */}
        <Card>
          <CardContent className="p-0">
            {isLoading ? (
              <ContentSkeleton type="list" rows={5} />
            ) : (
              <div className="divide-y">
                {ranks.map((rank, index) => (
                  <div
                    key={rank.id}
                    draggable
                    onDragStart={(e) => handleDragStart(e, index)}
                    onDragEnd={handleDragEnd}
                    onDragOver={(e) => handleDragOver(e, index)}
                    className={`px-4 py-3 hover:bg-muted/50 transition-colors cursor-move ${
                      draggedItem === index ? 'opacity-50 bg-muted' : ''
                    }`}
                  >
                    <div className="flex items-center gap-3">
                      {/* 드래그 핸들 (PC만) */}
                      <GripVertical className="h-5 w-5 text-muted-foreground flex-shrink-0 hidden md:block" />

                      {/* 순서 변경 버튼 */}
                      <ReorderButtons
                        onMoveUp={() => handleMoveItem(index, index - 1)}
                        onMoveDown={() => handleMoveItem(index, index + 1)}
                        isFirst={index === 0}
                        isLast={index === ranks.length - 1}
                        disabled={isSubmitting}
                        size="xs"
                      />

                      {/* 순서 번호 */}
                      <span className="text-sm text-muted-foreground w-8">
                        {index + 1}
                      </span>

                      {/* 직급명 */}
                      <span className="flex-1 min-w-0 font-medium">{rank.name}</span>

                      {/* 액션 버튼 (PC) */}
                      <div className="hidden sm:flex gap-1">
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => handleEdit(rank)}
                          className="h-8 w-8 p-0"
                          disabled={isSubmitting}
                        >
                          <Edit className="h-4 w-4" />
                          <span className="sr-only">수정</span>
                        </Button>
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => deleteDialog.single.open(String(rank.id))}
                          className="h-8 w-8 p-0 text-destructive hover:text-destructive"
                          disabled={deleteDialog.isPending}
                        >
                          <Trash2 className="h-4 w-4" />
                          <span className="sr-only">삭제</span>
                        </Button>
                      </div>
                    </div>

                    {/* 액션 버튼 (모바일) */}
                    <div className="flex sm:hidden gap-1 justify-end mt-2">
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => handleEdit(rank)}
                        className="h-8 w-8 p-0"
                        disabled={isSubmitting}
                      >
                        <Edit className="h-4 w-4" />
                        <span className="sr-only">수정</span>
                      </Button>
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => deleteDialog.single.open(String(rank.id))}
                        className="h-8 w-8 p-0 text-destructive hover:text-destructive"
                        disabled={deleteDialog.isPending}
                      >
                        <Trash2 className="h-4 w-4" />
                        <span className="sr-only">삭제</span>
                      </Button>
                    </div>
                  </div>
                ))}

                {ranks.length === 0 && (
                  <div className="px-4 py-8 text-center text-muted-foreground">
                    등록된 직급이 없습니다.
                  </div>
                )}
              </div>
            )}
          </CardContent>
        </Card>

        {/* 안내 문구 */}
        <p className="text-sm text-muted-foreground">
          ※ 화살표 버튼으로 순서를 변경할 수 있습니다.
        </p>
      </div>

      {/* 수정 다이얼로그 */}
      <RankDialog
        isOpen={dialogOpen}
        onOpenChange={setDialogOpen}
        mode={dialogMode}
        rank={selectedRank}
        onSubmit={handleDialogSubmit}
        isLoading={isSubmitting}
      />

      {/* 삭제 확인 다이얼로그 */}
      <DeleteConfirmDialog
        open={deleteDialog.single.isOpen}
        onOpenChange={deleteDialog.single.onOpenChange}
        onConfirm={deleteDialog.single.confirm}
        title="직급 삭제"
        description={
          <>
            &quot;{ranks.find(r => String(r.id) === deleteDialog.single.targetId)?.name}&quot; 직급을 삭제하시겠습니까?
            <br />
            <span className="text-destructive">
              이 직급을 사용 중인 사원이 있으면 해당 사원의 직급이 초기화됩니다.
            </span>
          </>
        }
        loading={deleteDialog.isPending}
      />
    </PageLayout>
  );
}