/**
 * V3 Action 메타 컴포넌트 렌더러
 * - 버튼 + CRUD 액션 실행
 * - config.steps 순차 처리
 * - 자체적으로 완전히 동작하는 액션 시스템
 */

"use client";

import React, { useState } from "react";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { ActionComponentConfig } from "@/lib/api/metaComponent";
import { tableTypeApi } from "@/lib/api/screen";
import { v2EventBus } from "@/lib/v2-core/events/EventBus";
import { V2_EVENTS } from "@/lib/v2-core/events/types";
import { apiClient } from "@/lib/api/client";
import { cn } from "@/lib/utils";
import { Loader2 } from "lucide-react";
import { toast } from "sonner";
import { useRouter } from "next/navigation";

interface ActionRendererProps {
  id: string;
  config: ActionComponentConfig;
  // 데이터
  formData?: Record<string, any>;
  selectedRowsData?: any[];
  // 컨텍스트
  tableName?: string;
  companyCode?: string;
  screenId?: number;
  userId?: string;
  // 콜백
  onRefresh?: () => void;
  // UI
  isDesignMode?: boolean;
  disabled?: boolean;
  className?: string;
}

export function ActionRenderer({
  id,
  config,
  formData = {},
  selectedRowsData = [],
  tableName,
  companyCode,
  screenId,
  userId,
  onRefresh,
  isDesignMode = false,
  disabled = false,
  className,
}: ActionRendererProps) {
  const [loading, setLoading] = useState(false);
  const [showConfirm, setShowConfirm] = useState(false);
  const router = useRouter();

  // 버튼 클릭 핸들러
  const handleClick = async () => {
    // 디자인 모드에서는 실행 안 함
    if (isDesignMode) {
      return;
    }

    // 활성화 조건 체크
    if (config.enableCondition) {
      const isEnabled = evaluateCondition(config.enableCondition);
      if (!isEnabled) {
        toast.warning("이 작업을 실행할 수 없습니다.");
        return;
      }
    }

    // 확인 대화상자가 있으면 먼저 표시
    if (config.confirmDialog) {
      setShowConfirm(true);
      return;
    }

    // 확인 없이 바로 실행
    await executeAction();
  };

  // 조건 평가 (간단한 버전)
  const evaluateCondition = (condition: any): boolean => {
    // TODO: 복잡한 조건 평가 로직 구현
    // 현재는 항상 true 반환
    return true;
  };

  // 액션 실행
  const executeAction = async () => {
    setShowConfirm(false);
    setLoading(true);

    try {
      // config.steps 순차 실행
      if (config.steps && config.steps.length > 0) {
        for (const step of config.steps) {
          await executeStep(step);
        }
      } else {
        toast.info("실행할 액션이 없습니다.");
      }
    } catch (error: any) {
      console.error("Action 실행 실패:", error);
      toast.error(error.message || "액션 실행에 실패했습니다.");
    } finally {
      setLoading(false);
    }
  };

  // 개별 스텝 실행
  const executeStep = async (step: any) => {
    switch (step.type) {
      case "save":
        await executeSaveStep(step);
        break;
      case "delete":
        await executeDeleteStep(step);
        break;
      case "refresh":
        executeRefreshStep(step);
        break;
      case "toast":
        executeToastStep(step);
        break;
      case "api":
        await executeApiStep(step);
        break;
      case "navigate":
        executeNavigateStep(step);
        break;
      default:
        console.warn(`알 수 없는 스텝 타입: ${step.type}`);
    }
  };

  // Save 스텝 실행
  const executeSaveStep = async (step: any) => {
    const targetTable = step.target || tableName;
    if (!targetTable) {
      throw new Error("저장할 테이블명이 없습니다.");
    }

    // formData에서 데이터 수집
    const dataToSave = { ...formData };
    
    // company_code 자동 추가
    if (companyCode && !dataToSave.company_code) {
      dataToSave.company_code = companyCode;
    }

    // 저장 모드 판단: 새로 생성 vs 수정
    const isEdit = step.mode === "edit" || (dataToSave && Object.keys(dataToSave).length > 0 && dataToSave.id);

    if (isEdit) {
      // 수정 모드
      await tableTypeApi.editTableData(targetTable, dataToSave, dataToSave);
      toast.success("수정 완료");
    } else {
      // 생성 모드
      await tableTypeApi.addTableData(targetTable, dataToSave);
      toast.success("저장 완료");
    }

    // 테이블 새로고침 이벤트 발행
    v2EventBus.emitSync(V2_EVENTS.TABLE_REFRESH, {
      tableName: targetTable,
      target: "single",
    });

    // onRefresh 콜백 호출
    onRefresh?.();
  };

  // Delete 스텝 실행
  const executeDeleteStep = async (step: any) => {
    const targetTable = step.target || tableName;
    if (!targetTable) {
      throw new Error("삭제할 테이블명이 없습니다.");
    }

    // 선택된 행 확인
    if (!selectedRowsData || selectedRowsData.length === 0) {
      toast.warning("삭제할 데이터를 선택해주세요.");
      return;
    }

    // 선택된 행 삭제
    await tableTypeApi.deleteTableData(targetTable, selectedRowsData);
    toast.success(`${selectedRowsData.length}개 항목이 삭제되었습니다.`);

    // 테이블 새로고침 이벤트 발행
    v2EventBus.emitSync(V2_EVENTS.TABLE_REFRESH, {
      tableName: targetTable,
      target: "single",
    });

    // onRefresh 콜백 호출
    onRefresh?.();
  };

  // Refresh 스텝 실행
  const executeRefreshStep = (step: any) => {
    const targetTable = step.target || tableName;

    if (targetTable) {
      // 특정 테이블 새로고침
      v2EventBus.emitSync(V2_EVENTS.TABLE_REFRESH, {
        tableName: targetTable,
        target: "single",
      });
    } else {
      // 전체 새로고침
      v2EventBus.emitSync(V2_EVENTS.TABLE_REFRESH, {
        target: "all",
      });
    }

    // onRefresh 콜백 호출
    onRefresh?.();

    toast.success("새로고침 완료");
  };

  // Toast 스텝 실행
  const executeToastStep = (step: any) => {
    const variant = step.variant || "info";
    const message = step.message || "알림";

    switch (variant) {
      case "success":
        toast.success(message);
        break;
      case "error":
        toast.error(message);
        break;
      case "warning":
        toast.warning(message);
        break;
      case "info":
      default:
        toast.info(message);
        break;
    }
  };

  // API 스텝 실행
  const executeApiStep = async (step: any) => {
    const method = (step.method || "GET").toLowerCase();
    const endpoint = step.endpoint;
    const body = step.body || {};

    if (!endpoint) {
      throw new Error("API 엔드포인트가 없습니다.");
    }

    let response;
    switch (method) {
      case "get":
        response = await apiClient.get(endpoint);
        break;
      case "post":
        response = await apiClient.post(endpoint, body);
        break;
      case "put":
        response = await apiClient.put(endpoint, body);
        break;
      case "delete":
        response = await apiClient.delete(endpoint, { data: body });
        break;
      default:
        throw new Error(`지원하지 않는 HTTP 메서드: ${method}`);
    }

    // 성공 메시지
    if (step.successMessage) {
      toast.success(step.successMessage);
    }

    return response;
  };

  // Navigate 스텝 실행
  const executeNavigateStep = (step: any) => {
    const path = step.path;
    if (!path) {
      console.warn("Navigate 스텝에 path가 없습니다.");
      return;
    }

    // Next.js router로 화면 이동
    router.push(path);
  };

  // 버튼 variant 매핑
  const getButtonVariant = () => {
    switch (config.buttonType) {
      case "primary":
        return "default";
      case "secondary":
        return "secondary";
      case "destructive":
        return "destructive";
      case "ghost":
        return "ghost";
      case "outline":
        return "outline";
      default:
        return "default";
    }
  };

  return (
    <>
      <Button
        id={id}
        variant={getButtonVariant()}
        onClick={handleClick}
        disabled={disabled || loading || isDesignMode}
        className={cn("h-8 text-xs sm:h-10 sm:text-sm", className)}
      >
        {loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
        {config.label}
      </Button>

      {/* 확인 대화상자 */}
      {config.confirmDialog && (
        <Dialog open={showConfirm} onOpenChange={setShowConfirm}>
          <DialogContent className="max-w-[95vw] sm:max-w-[500px]">
            <DialogHeader>
              <DialogTitle className="text-base sm:text-lg">
                {config.confirmDialog.title || "확인"}
              </DialogTitle>
              <DialogDescription className="text-xs sm:text-sm">
                {config.confirmDialog.message || "이 작업을 수행하시겠습니까?"}
              </DialogDescription>
            </DialogHeader>
            <DialogFooter className="gap-2 sm:gap-0">
              <Button
                variant="outline"
                onClick={() => setShowConfirm(false)}
                className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
              >
                취소
              </Button>
              <Button
                variant={config.buttonType === "destructive" ? "destructive" : "default"}
                onClick={executeAction}
                className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
              >
                확인
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      )}
    </>
  );
}
