"use client";

import React, { useState, useEffect, useCallback, useRef } from "react";
import {
  Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import { Plus, X, Loader2, Search, GripVertical, Users, ArrowDown, Layers } from "lucide-react";
import { toast } from "sonner";
import { createApprovalRequest } from "@/lib/api/approval";
import { getUserList } from "@/lib/api/user";

// 결재 방식
type ApprovalMode = "sequential" | "parallel";

interface ApproverRow {
  id: string;
  user_id: string;
  user_name: string;
  position_name: string;
  dept_name: string;
}

export interface ApprovalModalEventDetail {
  targetTable: string;
  targetRecordId: string;
  targetRecordData?: Record<string, any>;
  definitionId?: number;
  screenId?: number;
  buttonComponentId?: string;
}

interface ApprovalRequestModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  eventDetail?: ApprovalModalEventDetail | null;
}

interface UserSearchResult {
  user_id: string;
  user_name: string;
  position_name?: string;
  dept_name?: string;
  dept_code?: string;
  email?: string;
}

function genId(): string {
  return `a_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
}

export const ApprovalRequestModal: React.FC<ApprovalRequestModalProps> = ({
  open,
  onOpenChange,
  eventDetail,
}) => {
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");
  const [approvalMode, setApprovalMode] = useState<ApprovalMode>("sequential");
  const [approvers, setApprovers] = useState<ApproverRow[]>([]);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // 사용자 검색 상태
  const [searchOpen, setSearchOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [searchResults, setSearchResults] = useState<UserSearchResult[]>([]);
  const [isSearching, setIsSearching] = useState(false);
  const searchInputRef = useRef<HTMLInputElement>(null);
  const searchTimerRef = useRef<NodeJS.Timeout | null>(null);

  // 모달 닫힐 때 초기화
  useEffect(() => {
    if (!open) {
      setTitle("");
      setDescription("");
      setApprovalMode("sequential");
      setApprovers([]);
      setError(null);
      setSearchOpen(false);
      setSearchQuery("");
      setSearchResults([]);
    }
  }, [open]);

  // 사용자 검색 (디바운스)
  const searchUsers = useCallback(async (query: string) => {
    if (!query.trim() || query.trim().length < 1) {
      setSearchResults([]);
      return;
    }

    setIsSearching(true);
    try {
      const res = await getUserList({ search: query.trim(), limit: 20 });
      const data = res?.data || res || [];
      const users: UserSearchResult[] = Array.isArray(data) ? data : [];
      // 이미 추가된 결재자 제외
      const existingIds = new Set(approvers.map((a) => a.user_id));
      setSearchResults(users.filter((u) => !existingIds.has(u.user_id)));
    } catch {
      setSearchResults([]);
    } finally {
      setIsSearching(false);
    }
  }, [approvers]);

  useEffect(() => {
    if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
    if (!searchQuery.trim()) {
      setSearchResults([]);
      return;
    }
    searchTimerRef.current = setTimeout(() => {
      searchUsers(searchQuery);
    }, 300);
    return () => {
      if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
    };
  }, [searchQuery, searchUsers]);

  const addApprover = (user: UserSearchResult) => {
    setApprovers((prev) => [
      ...prev,
      {
        id: genId(),
        user_id: user.user_id,
        user_name: user.user_name,
        position_name: user.position_name || "",
        dept_name: user.dept_name || "",
      },
    ]);
    setSearchQuery("");
    setSearchResults([]);
    setSearchOpen(false);
  };

  const removeApprover = (id: string) => {
    setApprovers((prev) => prev.filter((a) => a.id !== id));
  };

  const moveApprover = (idx: number, direction: "up" | "down") => {
    setApprovers((prev) => {
      const next = [...prev];
      const targetIdx = direction === "up" ? idx - 1 : idx + 1;
      if (targetIdx < 0 || targetIdx >= next.length) return prev;
      [next[idx], next[targetIdx]] = [next[targetIdx], next[idx]];
      return next;
    });
  };

  const handleSubmit = async () => {
    if (!title.trim()) {
      setError("결재 제목을 입력해주세요.");
      return;
    }
    if (approvers.length === 0) {
      setError("결재자를 1명 이상 추가해주세요.");
      return;
    }
    if (!eventDetail?.targetTable || !eventDetail?.targetRecordId) {
      setError("결재 대상 정보가 없습니다. 레코드를 선택 후 다시 시도해주세요.");
      return;
    }

    setIsSubmitting(true);
    setError(null);

    const res = await createApprovalRequest({
      title: title.trim(),
      description: description.trim() || undefined,
      target_table: eventDetail.targetTable,
      target_record_id: eventDetail.targetRecordId,
      target_record_data: {
        ...eventDetail.targetRecordData,
        approval_mode: approvalMode,
      },
      screen_id: eventDetail.screenId,
      button_component_id: eventDetail.buttonComponentId,
      approvers: approvers.map((a, idx) => ({
        approver_id: a.user_id,
        approver_name: a.user_name,
        approver_position: a.position_name || undefined,
        approver_dept: a.dept_name || undefined,
        approver_label:
          approvalMode === "sequential"
            ? `${idx + 1}차 결재`
            : "동시 결재",
      })),
    });

    setIsSubmitting(false);

    if (res.success) {
      toast.success("결재 요청이 완료되었습니다.");
      onOpenChange(false);
    } else {
      setError(res.error || res.message || "결재 요청에 실패했습니다.");
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-[95vw] sm:max-w-[560px]">
        <DialogHeader>
          <DialogTitle className="text-base sm:text-lg">결재 상신</DialogTitle>
          <DialogDescription className="text-xs sm:text-sm">
            결재 방식을 선택하고 결재자를 검색하여 추가합니다.
          </DialogDescription>
        </DialogHeader>

        <div className="max-h-[65vh] space-y-4 overflow-y-auto pr-1">
          {/* 결재 제목 */}
          <div>
            <Label htmlFor="approval-title" className="text-xs sm:text-sm">
              결재 제목 <span className="text-destructive">*</span>
            </Label>
            <Input
              id="approval-title"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="결재 제목을 입력하세요"
              className="h-8 text-xs sm:h-10 sm:text-sm"
            />
          </div>

          {/* 결재 사유 */}
          <div>
            <Label htmlFor="approval-desc" className="text-xs sm:text-sm">
              결재 사유
            </Label>
            <Textarea
              id="approval-desc"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="결재 사유를 입력하세요 (선택사항)"
              className="min-h-[60px] text-xs sm:text-sm"
            />
          </div>

          {/* 결재 방식 */}
          <div>
            <Label className="text-xs sm:text-sm">결재 방식</Label>
            <div className="mt-1.5 grid grid-cols-2 gap-2">
              <button
                type="button"
                onClick={() => setApprovalMode("sequential")}
                className={`flex items-center gap-2 rounded-md border p-3 text-left transition-colors ${
                  approvalMode === "sequential"
                    ? "border-primary bg-primary/5 ring-1 ring-primary"
                    : "hover:bg-muted/50"
                }`}
              >
                <ArrowDown className="h-4 w-4 shrink-0" />
                <div>
                  <p className="text-xs font-medium sm:text-sm">다단 결재</p>
                  <p className="text-muted-foreground text-[10px]">순차적으로 결재</p>
                </div>
              </button>
              <button
                type="button"
                onClick={() => setApprovalMode("parallel")}
                className={`flex items-center gap-2 rounded-md border p-3 text-left transition-colors ${
                  approvalMode === "parallel"
                    ? "border-primary bg-primary/5 ring-1 ring-primary"
                    : "hover:bg-muted/50"
                }`}
              >
                <Layers className="h-4 w-4 shrink-0" />
                <div>
                  <p className="text-xs font-medium sm:text-sm">동시 결재</p>
                  <p className="text-muted-foreground text-[10px]">모든 결재자 동시 진행</p>
                </div>
              </button>
            </div>
          </div>

          {/* 결재자 추가 (사용자 검색) */}
          <div>
            <div className="mb-2 flex items-center justify-between">
              <Label className="text-xs sm:text-sm">
                결재자 <span className="text-destructive">*</span>
              </Label>
              <span className="text-muted-foreground text-[10px]">
                {approvers.length}명 선택됨
              </span>
            </div>

            {/* 검색 입력 */}
            <div className="relative">
              <Search className="text-muted-foreground absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2" />
              <Input
                ref={searchInputRef}
                value={searchQuery}
                onChange={(e) => {
                  setSearchQuery(e.target.value);
                  setSearchOpen(true);
                }}
                onFocus={() => setSearchOpen(true)}
                placeholder="이름 또는 사번으로 검색..."
                className="h-8 pl-9 text-xs sm:h-10 sm:text-sm"
              />

              {/* 검색 결과 드롭다운 */}
              {searchOpen && searchQuery.trim() && (
                <div className="absolute top-full left-0 z-50 mt-1 w-full rounded-md border bg-popover shadow-lg">
                  {isSearching ? (
                    <div className="flex items-center justify-center p-4">
                      <Loader2 className="text-muted-foreground h-4 w-4 animate-spin" />
                      <span className="text-muted-foreground ml-2 text-xs">검색 중...</span>
                    </div>
                  ) : searchResults.length === 0 ? (
                    <div className="p-4 text-center">
                      <p className="text-muted-foreground text-xs">검색 결과가 없습니다.</p>
                    </div>
                  ) : (
                    <div className="max-h-48 overflow-y-auto">
                      {searchResults.map((user) => (
                        <button
                          key={user.user_id}
                          type="button"
                          onClick={() => addApprover(user)}
                          className="flex w-full items-center gap-3 px-3 py-2 text-left transition-colors hover:bg-accent"
                        >
                          <div className="bg-muted flex h-8 w-8 shrink-0 items-center justify-center rounded-full">
                            <Users className="h-4 w-4" />
                          </div>
                          <div className="min-w-0 flex-1">
                            <p className="truncate text-xs font-medium sm:text-sm">
                              {user.user_name}
                              <span className="text-muted-foreground ml-1 text-[10px]">
                                ({user.user_id})
                              </span>
                            </p>
                            <p className="text-muted-foreground truncate text-[10px]">
                              {[user.dept_name, user.position_name].filter(Boolean).join(" / ") || "-"}
                            </p>
                          </div>
                          <Plus className="text-muted-foreground h-4 w-4 shrink-0" />
                        </button>
                      ))}
                    </div>
                  )}
                </div>
              )}
            </div>

            {/* 클릭 외부 영역 닫기 */}
            {searchOpen && (
              <div
                className="fixed inset-0 z-40"
                onClick={() => setSearchOpen(false)}
              />
            )}

            {/* 선택된 결재자 목록 */}
            {approvers.length === 0 ? (
              <p className="text-muted-foreground mt-3 rounded-md border border-dashed p-4 text-center text-xs">
                위 검색창에서 결재자를 검색하여 추가하세요
              </p>
            ) : (
              <div className="mt-3 space-y-2">
                {approvers.map((approver, idx) => (
                  <div
                    key={approver.id}
                    className="bg-muted/30 flex items-center gap-2 rounded-md border p-2"
                  >
                    {/* 순서 표시 */}
                    {approvalMode === "sequential" ? (
                      <div className="flex shrink-0 flex-col items-center gap-0.5">
                        <button
                          type="button"
                          onClick={() => moveApprover(idx, "up")}
                          disabled={idx === 0}
                          className="text-muted-foreground hover:text-foreground disabled:opacity-30"
                        >
                          <GripVertical className="h-3 w-3 rotate-90" />
                        </button>
                        <Badge variant="outline" className="h-5 min-w-[24px] justify-center px-1 text-[10px]">
                          {idx + 1}
                        </Badge>
                        <button
                          type="button"
                          onClick={() => moveApprover(idx, "down")}
                          disabled={idx === approvers.length - 1}
                          className="text-muted-foreground hover:text-foreground disabled:opacity-30"
                        >
                          <GripVertical className="h-3 w-3 rotate-90" />
                        </button>
                      </div>
                    ) : (
                      <Badge variant="secondary" className="h-5 shrink-0 px-1.5 text-[10px]">
                        동시
                      </Badge>
                    )}

                    {/* 사용자 정보 */}
                    <div className="min-w-0 flex-1">
                      <p className="truncate text-xs font-medium">
                        {approver.user_name}
                        <span className="text-muted-foreground ml-1 text-[10px]">
                          ({approver.user_id})
                        </span>
                      </p>
                      <p className="text-muted-foreground truncate text-[10px]">
                        {[approver.dept_name, approver.position_name].filter(Boolean).join(" / ") || "-"}
                      </p>
                    </div>

                    {/* 제거 버튼 */}
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon"
                      className="h-6 w-6 shrink-0"
                      onClick={() => removeApprover(approver.id)}
                    >
                      <X className="h-3 w-3" />
                    </Button>
                  </div>
                ))}

                {/* 결재 흐름 시각화 */}
                {approvalMode === "sequential" && approvers.length > 1 && (
                  <p className="text-muted-foreground text-center text-[10px]">
                    {approvers.map((a) => a.user_name).join(" → ")}
                  </p>
                )}
              </div>
            )}
          </div>

          {/* 에러 메시지 */}
          {error && (
            <div className="bg-destructive/10 rounded-md p-2">
              <p className="text-destructive text-xs">{error}</p>
            </div>
          )}
        </div>

        <DialogFooter className="gap-2 sm:gap-0">
          <Button
            variant="outline"
            onClick={() => onOpenChange(false)}
            disabled={isSubmitting}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            취소
          </Button>
          <Button
            onClick={handleSubmit}
            disabled={isSubmitting || approvers.length === 0}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            {isSubmitting ? (
              <>
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                요청 중...
              </>
            ) : (
              `결재 상신 (${approvers.length}명)`
            )}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};

export default ApprovalRequestModal;
