"use client";

/**
 * 메일 발송 노드 속성 편집
 * - 메일관리에서 등록한 계정을 선택하여 발송
 * - 변수 태그 에디터로 본문 편집
 */

import { useEffect, useState, useCallback, useMemo } from "react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Switch } from "@/components/ui/switch";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Plus,
  Trash2,
  Mail,
  Server,
  FileText,
  Settings,
  RefreshCw,
  CheckCircle,
  AlertCircle,
  User,
} from "lucide-react";
import { useFlowEditorStore } from "@/lib/stores/flowEditorStore";
import { getMailAccounts, type MailAccount } from "@/lib/api/mail";
import type { EmailActionNodeData } from "@/types/node-editor";
import { VariableTagEditor, type VariableInfo } from "../../editors/VariableTagEditor";

interface EmailActionPropertiesProps {
  nodeId: string;
  data: EmailActionNodeData;
}

export function EmailActionProperties({ nodeId, data }: EmailActionPropertiesProps) {
  const { updateNode, nodes, edges } = useFlowEditorStore();

  // 메일 계정 목록
  const [mailAccounts, setMailAccounts] = useState<MailAccount[]>([]);
  const [isLoadingAccounts, setIsLoadingAccounts] = useState(false);
  const [accountError, setAccountError] = useState<string | null>(null);

  // 🆕 플로우에서 사용 가능한 변수 목록 계산
  const availableVariables = useMemo<VariableInfo[]>(() => {
    const variables: VariableInfo[] = [];

    // 기본 시스템 변수
    variables.push(
      { name: "timestamp", displayName: "현재 시간", description: "메일 발송 시점의 타임스탬프" },
      { name: "sourceData", displayName: "소스 데이터", description: "전체 소스 데이터 (JSON)" },
    );

    // 현재 노드에 연결된 소스 노드들에서 필드 정보 수집
    const incomingEdges = edges.filter((e) => e.target === nodeId);

    for (const edge of incomingEdges) {
      const sourceNode = nodes.find((n) => n.id === edge.source);
      if (!sourceNode) continue;

      const nodeData = sourceNode.data as any;

      // 테이블 소스 노드인 경우
      if (sourceNode.type === "tableSource" && nodeData.fields) {
        const tableName = nodeData.tableName || "테이블";
        nodeData.fields.forEach((field: any) => {
          variables.push({
            name: field.name,
            displayName: field.displayName || field.label || field.name,
            type: field.type,
            description: `${tableName} 테이블의 필드`,
          });
        });
      }

      // 외부 DB 소스 노드인 경우
      if (sourceNode.type === "externalDBSource" && nodeData.fields) {
        const tableName = nodeData.tableName || "외부 테이블";
        nodeData.fields.forEach((field: any) => {
          variables.push({
            name: field.name,
            displayName: field.displayName || field.label || field.name,
            type: field.type,
            description: `${tableName} (외부 DB) 필드`,
          });
        });
      }

      // REST API 소스 노드인 경우
      if (sourceNode.type === "restAPISource" && nodeData.responseFields) {
        nodeData.responseFields.forEach((field: any) => {
          variables.push({
            name: field.name,
            displayName: field.displayName || field.label || field.name,
            type: field.type,
            description: "REST API 응답 필드",
          });
        });
      }

      // 데이터 변환 노드인 경우 - 출력 필드 추가
      if (sourceNode.type === "dataTransform" && nodeData.transformations) {
        nodeData.transformations.forEach((transform: any) => {
          if (transform.targetField) {
            variables.push({
              name: transform.targetField,
              displayName: transform.targetField,
              description: "데이터 변환 결과 필드",
            });
          }
        });
      }
    }

    // 중복 제거
    const uniqueVariables = variables.filter((v, index, self) => index === self.findIndex((t) => t.name === v.name));

    return uniqueVariables;
  }, [nodes, edges, nodeId]);

  // 로컬 상태
  const [displayName, setDisplayName] = useState(data.displayName || "메일 발송");

  // 계정 선택
  const [selectedAccountId, setSelectedAccountId] = useState(data.accountId || "");

  // 🆕 수신자 컴포넌트 사용 여부
  const [useRecipientComponent, setUseRecipientComponent] = useState(data.useRecipientComponent ?? false);
  const [recipientToField, setRecipientToField] = useState(data.recipientToField || "mailTo");
  const [recipientCcField, setRecipientCcField] = useState(data.recipientCcField || "mailCc");

  // 메일 내용
  const [to, setTo] = useState(data.to || "");
  const [cc, setCc] = useState(data.cc || "");
  const [bcc, setBcc] = useState(data.bcc || "");
  const [subject, setSubject] = useState(data.subject || "");
  const [body, setBody] = useState(data.body || "");
  const [bodyType, setBodyType] = useState<"text" | "html">(data.bodyType || "text");

  // 고급 설정
  const [replyTo, setReplyTo] = useState(data.replyTo || "");
  const [priority, setPriority] = useState<"high" | "normal" | "low">(data.priority || "normal");
  const [timeout, setTimeout] = useState(data.options?.timeout?.toString() || "30000");
  const [retryCount, setRetryCount] = useState(data.options?.retryCount?.toString() || "3");

  // 메일 계정 목록 로드
  const loadMailAccounts = useCallback(async () => {
    setIsLoadingAccounts(true);
    setAccountError(null);
    try {
      const accounts = await getMailAccounts();
      setMailAccounts(accounts.filter((acc) => acc.status === "active"));
    } catch (error) {
      console.error("메일 계정 로드 실패:", error);
      setAccountError("메일 계정을 불러오는데 실패했습니다");
    } finally {
      setIsLoadingAccounts(false);
    }
  }, []);

  // 컴포넌트 마운트 시 메일 계정 로드
  useEffect(() => {
    loadMailAccounts();
  }, [loadMailAccounts]);

  // 데이터 변경 시 로컬 상태 동기화
  useEffect(() => {
    setDisplayName(data.displayName || "메일 발송");
    setSelectedAccountId(data.accountId || "");
    setUseRecipientComponent(data.useRecipientComponent ?? false);
    setRecipientToField(data.recipientToField || "mailTo");
    setRecipientCcField(data.recipientCcField || "mailCc");
    setTo(data.to || "");
    setCc(data.cc || "");
    setBcc(data.bcc || "");
    setSubject(data.subject || "");
    setBody(data.body || "");
    setBodyType(data.bodyType || "text");
    setReplyTo(data.replyTo || "");
    setPriority(data.priority || "normal");
    setTimeout(data.options?.timeout?.toString() || "30000");
    setRetryCount(data.options?.retryCount?.toString() || "3");
  }, [data]);

  // 선택된 계정 정보
  const selectedAccount = mailAccounts.find((acc) => acc.id === selectedAccountId);

  // 노드 업데이트 함수
  const updateNodeData = useCallback(
    (updates: Partial<EmailActionNodeData>) => {
      updateNode(nodeId, {
        ...data,
        ...updates,
      });
    },
    [nodeId, data, updateNode],
  );

  // 표시명 변경
  const handleDisplayNameChange = (value: string) => {
    setDisplayName(value);
    updateNodeData({ displayName: value });
  };

  // 계정 선택 변경
  const handleAccountChange = (accountId: string) => {
    setSelectedAccountId(accountId);
    const account = mailAccounts.find((acc) => acc.id === accountId);
    updateNodeData({
      accountId,
      // 계정의 이메일을 발신자로 자동 설정
      from: account?.email || "",
    });
  };

  // 메일 내용 업데이트
  const updateMailContent = useCallback(() => {
    updateNodeData({
      to,
      cc: cc || undefined,
      bcc: bcc || undefined,
      subject,
      body,
      bodyType,
      replyTo: replyTo || undefined,
      priority,
    });
  }, [to, cc, bcc, subject, body, bodyType, replyTo, priority, updateNodeData]);

  // 옵션 업데이트
  const updateOptions = useCallback(() => {
    updateNodeData({
      options: {
        timeout: parseInt(timeout) || 30000,
        retryCount: parseInt(retryCount) || 3,
      },
    });
  }, [timeout, retryCount, updateNodeData]);

  return (
    <div className="space-y-4 p-4">
      {/* 표시명 */}
      <div className="space-y-2">
        <Label className="text-xs font-medium">표시명</Label>
        <Input
          value={displayName}
          onChange={(e) => handleDisplayNameChange(e.target.value)}
          placeholder="메일 발송"
          className="h-8 text-sm"
        />
      </div>

      <Tabs defaultValue="account" className="w-full">
        <TabsList className="grid w-full grid-cols-4">
          <TabsTrigger value="account" className="text-xs">
            <User className="mr-1 h-3 w-3" />
            계정
          </TabsTrigger>
          <TabsTrigger value="mail" className="text-xs">
            <Mail className="mr-1 h-3 w-3" />
            메일
          </TabsTrigger>
          <TabsTrigger value="content" className="text-xs">
            <FileText className="mr-1 h-3 w-3" />
            본문
          </TabsTrigger>
          <TabsTrigger value="options" className="text-xs">
            <Settings className="mr-1 h-3 w-3" />
            옵션
          </TabsTrigger>
        </TabsList>

        {/* 계정 선택 탭 */}
        <TabsContent value="account" className="space-y-3 pt-3">
          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <Label className="text-xs">발송 계정 선택 *</Label>
              <Button
                variant="ghost"
                size="sm"
                onClick={loadMailAccounts}
                disabled={isLoadingAccounts}
                className="h-6 px-2"
              >
                <RefreshCw className={`h-3 w-3 ${isLoadingAccounts ? "animate-spin" : ""}`} />
              </Button>
            </div>

            {accountError && (
              <div className="flex items-center gap-2 text-xs text-red-500">
                <AlertCircle className="h-3 w-3" />
                {accountError}
              </div>
            )}

            <Select value={selectedAccountId} onValueChange={handleAccountChange} disabled={isLoadingAccounts}>
              <SelectTrigger className="h-8 text-sm">
                <SelectValue placeholder={isLoadingAccounts ? "로딩 중..." : "메일 계정을 선택하세요"} />
              </SelectTrigger>
              <SelectContent>
                {mailAccounts.length === 0 ? (
                  <div className="p-2 text-xs text-gray-500">
                    등록된 메일 계정이 없습니다.
                    <br />
                    관리자 &gt; 메일관리 &gt; 계정관리에서 추가하세요.
                  </div>
                ) : (
                  mailAccounts.map((account) => (
                    <SelectItem key={account.id} value={account.id}>
                      <div className="flex items-center gap-2">
                        <span className="font-medium">{account.name}</span>
                        <span className="text-xs text-gray-500">({account.email})</span>
                      </div>
                    </SelectItem>
                  ))
                )}
              </SelectContent>
            </Select>
          </div>

          {/* 선택된 계정 정보 표시 */}
          {selectedAccount && (
            <Card className="border-green-200 bg-green-50">
              <CardContent className="space-y-2 p-3">
                <div className="flex items-center gap-2 text-green-700">
                  <CheckCircle className="h-4 w-4" />
                  <span className="text-sm font-medium">선택된 계정</span>
                </div>
                <div className="space-y-1 text-xs text-green-800">
                  <div>
                    <strong>이름:</strong> {selectedAccount.name}
                  </div>
                  <div>
                    <strong>이메일:</strong> {selectedAccount.email}
                  </div>
                  <div>
                    <strong>SMTP:</strong> {selectedAccount.smtpHost}:{selectedAccount.smtpPort}
                  </div>
                </div>
              </CardContent>
            </Card>
          )}

          {!selectedAccount && mailAccounts.length > 0 && (
            <Card className="border-yellow-200 bg-yellow-50">
              <CardContent className="p-3 text-xs text-yellow-700">
                <div className="flex items-center gap-2">
                  <AlertCircle className="h-4 w-4" />
                  <span>메일 발송을 위해 계정을 선택해주세요.</span>
                </div>
              </CardContent>
            </Card>
          )}

          {mailAccounts.length === 0 && !isLoadingAccounts && (
            <Card className="bg-gray-50">
              <CardContent className="p-3 text-xs text-gray-600">
                <div className="space-y-2">
                  <div className="font-medium">메일 계정 등록 방법:</div>
                  <ol className="list-inside list-decimal space-y-1">
                    <li>관리자 메뉴로 이동</li>
                    <li>메일관리 &gt; 계정관리 선택</li>
                    <li>새 계정 추가 버튼 클릭</li>
                    <li>SMTP 정보 입력 후 저장</li>
                  </ol>
                </div>
              </CardContent>
            </Card>
          )}
        </TabsContent>

        {/* 메일 설정 탭 */}
        <TabsContent value="mail" className="space-y-3 pt-3">
          {/* 발신자는 선택된 계정에서 자동으로 설정됨 */}
          {selectedAccount && (
            <div className="space-y-2">
              <Label className="text-xs">발신자 (From)</Label>
              <div className="flex h-8 items-center rounded-md border bg-gray-100 px-3 py-2 text-sm">
                {selectedAccount.email}
              </div>
              <p className="text-xs text-gray-500">선택한 계정의 이메일 주소가 자동으로 사용됩니다.</p>
            </div>
          )}

          {/* 🆕 수신자 컴포넌트 사용 옵션 */}
          <Card className={useRecipientComponent ? "border-blue-200 bg-blue-50" : "bg-gray-50"}>
            <CardContent className="space-y-3 p-3">
              <div className="flex items-center justify-between">
                <div className="space-y-1">
                  <Label className="text-xs font-medium">수신자 컴포넌트 사용</Label>
                  <p className="text-xs text-gray-500">
                    화면에 배치한 "메일 수신자 선택" 컴포넌트의 값을 자동으로 사용합니다.
                  </p>
                </div>
                <Switch
                  checked={useRecipientComponent}
                  onCheckedChange={(checked) => {
                    setUseRecipientComponent(checked);
                    if (checked) {
                      // 체크 시 자동으로 변수 설정
                      updateNodeData({
                        useRecipientComponent: true,
                        recipientToField,
                        recipientCcField,
                        to: `{{${recipientToField}}}`,
                        cc: `{{${recipientCcField}}}`,
                      });
                      setTo(`{{${recipientToField}}}`);
                      setCc(`{{${recipientCcField}}}`);
                    } else {
                      updateNodeData({
                        useRecipientComponent: false,
                        to: "",
                        cc: "",
                      });
                      setTo("");
                      setCc("");
                    }
                  }}
                />
              </div>

              {/* 필드명 설정 (수신자 컴포넌트 사용 시) */}
              {useRecipientComponent && (
                <div className="space-y-2 border-t border-blue-200 pt-2">
                  <div className="grid grid-cols-2 gap-2">
                    <div className="space-y-1">
                      <Label className="text-xs">수신자 필드명</Label>
                      <Input
                        value={recipientToField}
                        onChange={(e) => {
                          const newField = e.target.value;
                          setRecipientToField(newField);
                          setTo(`{{${newField}}}`);
                          updateNodeData({
                            recipientToField: newField,
                            to: `{{${newField}}}`,
                          });
                        }}
                        placeholder="mailTo"
                        className="h-7 text-xs"
                      />
                    </div>
                    <div className="space-y-1">
                      <Label className="text-xs">참조 필드명</Label>
                      <Input
                        value={recipientCcField}
                        onChange={(e) => {
                          const newField = e.target.value;
                          setRecipientCcField(newField);
                          setCc(`{{${newField}}}`);
                          updateNodeData({
                            recipientCcField: newField,
                            cc: `{{${newField}}}`,
                          });
                        }}
                        placeholder="mailCc"
                        className="h-7 text-xs"
                      />
                    </div>
                  </div>
                  <div className="rounded bg-blue-100 p-2 text-xs text-blue-600">
                    <strong>자동 설정됨:</strong>
                    <br />
                    수신자: <code className="rounded bg-white px-1">{`{{${recipientToField}}}`}</code>
                    <br />
                    참조: <code className="rounded bg-white px-1">{`{{${recipientCcField}}}`}</code>
                  </div>
                </div>
              )}
            </CardContent>
          </Card>

          {/* 수신자 직접 입력 (컴포넌트 미사용 시) */}
          {!useRecipientComponent && (
            <>
              <div className="space-y-2">
                <Label className="text-xs">수신자 (To) *</Label>
                <Input
                  value={to}
                  onChange={(e) => setTo(e.target.value)}
                  onBlur={updateMailContent}
                  placeholder="recipient@example.com (쉼표로 구분, {{변수}} 사용 가능)"
                  className="h-8 text-sm"
                />
              </div>

              <div className="space-y-2">
                <Label className="text-xs">참조 (CC)</Label>
                <Input
                  value={cc}
                  onChange={(e) => setCc(e.target.value)}
                  onBlur={updateMailContent}
                  placeholder="cc@example.com"
                  className="h-8 text-sm"
                />
              </div>
            </>
          )}

          <div className="space-y-2">
            <Label className="text-xs">숨은 참조 (BCC)</Label>
            <Input
              value={bcc}
              onChange={(e) => setBcc(e.target.value)}
              onBlur={updateMailContent}
              placeholder="bcc@example.com"
              className="h-8 text-sm"
            />
          </div>

          <div className="space-y-2">
            <Label className="text-xs">회신 주소 (Reply-To)</Label>
            <Input
              value={replyTo}
              onChange={(e) => setReplyTo(e.target.value)}
              onBlur={updateMailContent}
              placeholder="reply@example.com"
              className="h-8 text-sm"
            />
          </div>

          <div className="space-y-2">
            <Label className="text-xs">우선순위</Label>
            <Select
              value={priority}
              onValueChange={(v: "high" | "normal" | "low") => {
                setPriority(v);
                updateNodeData({ priority: v });
              }}
            >
              <SelectTrigger className="h-8 text-sm">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="high">높음</SelectItem>
                <SelectItem value="normal">보통</SelectItem>
                <SelectItem value="low">낮음</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </TabsContent>

        {/* 본문 탭 */}
        <TabsContent value="content" className="space-y-3 pt-3">
          <div className="space-y-2">
            <Label className="text-xs">제목 *</Label>
            <Input
              value={subject}
              onChange={(e) => setSubject(e.target.value)}
              onBlur={updateMailContent}
              placeholder="메일 제목 ({{변수}} 사용 가능)"
              className="h-8 text-sm"
            />
          </div>

          <div className="space-y-2">
            <Label className="text-xs">본문 형식</Label>
            <Select
              value={bodyType}
              onValueChange={(v: "text" | "html") => {
                setBodyType(v);
                updateNodeData({ bodyType: v });
              }}
            >
              <SelectTrigger className="h-8 text-sm">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="text">텍스트 (변수 태그 에디터)</SelectItem>
                <SelectItem value="html">HTML (직접 입력)</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <div className="space-y-2">
            <Label className="text-xs">본문 내용</Label>

            {/* 텍스트 형식: 변수 태그 에디터 사용 */}
            {bodyType === "text" && (
              <VariableTagEditor
                value={body}
                onChange={(newBody) => {
                  setBody(newBody);
                  updateNodeData({ body: newBody });
                }}
                variables={availableVariables}
                placeholder="메일 본문을 입력하세요. @ 또는 / 키로 변수를 삽입할 수 있습니다."
                minHeight="200px"
              />
            )}

            {/* HTML 형식: 직접 입력 */}
            {bodyType === "html" && (
              <Textarea
                value={body}
                onChange={(e) => setBody(e.target.value)}
                onBlur={updateMailContent}
                placeholder="<html><body>...</body></html>"
                className="min-h-[200px] font-mono text-sm"
              />
            )}
          </div>

          {/* 변수 안내 (HTML 모드에서만 표시) */}
          {bodyType === "html" && (
            <Card className="bg-gray-50">
              <CardContent className="p-3 text-xs text-gray-600">
                <div className="mb-1 font-medium">사용 가능한 템플릿 변수:</div>
                {availableVariables.slice(0, 5).map((v) => (
                  <code key={v.name} className="block">
                    {`{{${v.name}}}`} - {v.displayName}
                  </code>
                ))}
                {availableVariables.length > 5 && (
                  <span className="text-gray-400">...외 {availableVariables.length - 5}개</span>
                )}
              </CardContent>
            </Card>
          )}

          {/* 변수 태그 에디터 안내 (텍스트 모드에서만 표시) */}
          {bodyType === "text" && (
            <Card className="border-blue-200 bg-blue-50">
              <CardContent className="p-3 text-xs text-blue-700">
                <div className="mb-1 font-medium">변수 삽입 방법:</div>
                <ul className="list-inside list-disc space-y-0.5">
                  <li>
                    <kbd className="rounded bg-blue-100 px-1">@</kbd> 또는{" "}
                    <kbd className="rounded bg-blue-100 px-1">/</kbd> 키를 눌러 변수 목록 열기
                  </li>
                  <li>툴바의 "변수 삽입" 버튼 클릭</li>
                  <li>삽입된 변수는 파란색 태그로 표시됩니다</li>
                </ul>
              </CardContent>
            </Card>
          )}
        </TabsContent>

        {/* 옵션 탭 */}
        <TabsContent value="options" className="space-y-3 pt-3">
          <div className="space-y-2">
            <Label className="text-xs">타임아웃 (ms)</Label>
            <Input
              type="number"
              value={timeout}
              onChange={(e) => setTimeout(e.target.value)}
              onBlur={updateOptions}
              placeholder="30000"
              className="h-8 text-sm"
            />
          </div>

          <div className="space-y-2">
            <Label className="text-xs">재시도 횟수</Label>
            <Input
              type="number"
              value={retryCount}
              onChange={(e) => setRetryCount(e.target.value)}
              onBlur={updateOptions}
              placeholder="3"
              className="h-8 text-sm"
            />
          </div>
        </TabsContent>
      </Tabs>
    </div>
  );
}
