'use client';

import { useState, useEffect, useCallback } from 'react';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { Briefcase, 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 { TitleDialog } from './TitleDialog';
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
import { useDeleteDialog } from '@/hooks/useDeleteDialog';
import { toast } from 'sonner';
import type { Title } from './types';
import {
  getTitles,
  createTitle,
  updateTitle,
  deleteTitle,
  reorderTitles,
} from './actions';
import { isNextRedirectError } from '@/lib/utils/redirect-error';

export function TitleManagement() {
  // 직책 데이터
  const [titles, setTitles] = useState<Title[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isSubmitting, setIsSubmitting] = useState(false);

  // 입력 필드
  const [newTitleName, setNewTitleName] = useState('');

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

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

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

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

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

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

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

  // 직책 수정 다이얼로그 열기
  const handleEdit = (title: Title) => {
    setSelectedTitle(title);
    setDialogMode('edit');
    setDialogOpen(true);
  };

  // 다이얼로그 제출
  const handleDialogSubmit = async (name: string) => {
    if (dialogMode === 'edit' && selectedTitle) {
      try {
        setIsSubmitting(true);
        const result = await updateTitle(selectedTitle.id, { name });
        if (result.success) {
          setTitles(prev => prev.map(t =>
            t.id === selectedTitle.id ? { ...t, name } : t
          ));
          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 = titles.map((title, idx) => ({
        id: title.id,
        sort_order: idx + 1,
      }));
      const result = await reorderTitles(items);
      if (result.success) {
        toast.success('순서가 변경되었습니다.');
      } else {
        toast.error(result.error || '순서 변경에 실패했습니다.');
        loadTitles();
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('순서 변경 실패:', error);
      toast.error('순서 변경에 실패했습니다.');
      // 실패시 원래 순서로 복구
      loadTitles();
    }
  };

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

    const newTitles = [...titles];
    const draggedTitle = newTitles[draggedItem];
    newTitles.splice(draggedItem, 1);
    newTitles.splice(index, 0, draggedTitle);

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

    setTitles(reorderedTitles);
    setDraggedItem(index);
  };

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

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

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

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

      <div className="space-y-4">
        {/* 직책 추가 입력 영역 */}
        <Card>
          <CardContent className="p-4">
            <div className="flex gap-2">
              <Input
                value={newTitleName}
                onChange={(e) => setNewTitleName(e.target.value)}
                onKeyDown={handleKeyDown}
                placeholder="직책명을 입력하세요"
                className="flex-1"
                disabled={isSubmitting}
              />
              <Button
                onClick={handleQuickAdd}
                disabled={!newTitleName.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">
                {titles.map((title, index) => (
                  <div
                    key={title.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 === titles.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">{title.name}</span>

                      {/* 액션 버튼 (PC) */}
                      <div className="hidden sm:flex gap-1">
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => handleEdit(title)}
                          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(title.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(title)}
                        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(title.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>
                ))}

                {titles.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>

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

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