'use client';

/**
 * IntegratedDetailTemplate - 통합 상세/등록/수정 페이지 템플릿
 *
 * 등록(create), 상세(view), 수정(edit) 모드를 하나의 config로 통합
 * - 기존 AccountDetail, CardForm 등의 패턴을 일반화
 * - 필드 정의 기반 자동 렌더링
 * - 커스텀 렌더러 지원 (renderView, renderForm, renderField)
 */

import { useState, useEffect, useCallback, useMemo, forwardRef, useImperativeHandle } from 'react';
import { useRouter, useParams } from 'next/navigation';
import { usePermission } from '@/hooks/usePermission';
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { toast } from 'sonner';
import { FieldInput } from './FieldInput';
import { DetailSection, DetailGrid, DetailField, DetailActions, DetailSectionSkeleton } from './components';
import type {
  IntegratedDetailTemplateProps,
  IntegratedDetailTemplateRef,
  DetailMode,
  FieldDefinition,
  FieldOption,
  ValidationRule,
} from './types';

// Inner component with forwardRef
function IntegratedDetailTemplateInner<T extends Record<string, unknown>>(
  {
    config,
    mode: initialMode,
    initialData,
    itemId,
    isLoading = false,
    onSubmit,
    onDelete,
    onCancel,
    onModeChange,
    onEdit: onEditProp,
    renderView,
    renderForm,
    renderField,
    headerActions,
    headerActionItems,
    beforeContent,
    afterContent,
    buttonPosition = 'bottom',
    stickyButtons = true,
  }: IntegratedDetailTemplateProps<T>,
  ref: React.ForwardedRef<IntegratedDetailTemplateRef>
) {
  const router = useRouter();
  const params = useParams();
  const locale = (params.locale as string) || 'ko';
  const { canCreate: permCanCreate, canUpdate: permCanUpdate, canDelete: permCanDelete } = usePermission();

  // ===== 상태 =====
  const [mode, setMode] = useState<DetailMode>(initialMode);
  const [formData, setFormData] = useState<Record<string, unknown>>({});
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [showDeleteDialog, setShowDeleteDialog] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [dynamicOptions, setDynamicOptions] = useState<Record<string, FieldOption[]>>({});

  // ===== Ref 메서드 노출 (DevFill 등에서 사용) =====
  useImperativeHandle(ref, () => ({
    setFormData: (data: Record<string, unknown>) => {
      setFormData(prev => ({ ...prev, ...data }));
    },
    getFormData: () => formData,
    setFieldValue: (key: string, value: unknown) => {
      setFormData(prev => ({ ...prev, [key]: value }));
    },
    validate: () => {
      const newErrors: Record<string, string> = {};
      config.fields.forEach((field) => {
        const value = formData[field.key];
        if (field.required && (value === null || value === undefined || value === '')) {
          newErrors[field.key] = `${field.label}은(는) 필수입니다.`;
        }
      });
      setErrors(newErrors);
      return Object.keys(newErrors).length === 0;
    },
    reset: () => {
      if (initialData) {
        const transformed = config.transformInitialData
          ? config.transformInitialData(initialData)
          : (initialData as Record<string, unknown>);
        setFormData(transformed);
      } else {
        const defaultData: Record<string, unknown> = {};
        config.fields.forEach((field) => {
          if (field.defaultValue !== undefined) {
            defaultData[field.key] = field.defaultValue;
          } else if (field.type === 'checkbox') {
            defaultData[field.key] = false;
          } else {
            defaultData[field.key] = '';
          }
        });
        setFormData(defaultData);
      }
      setErrors({});
    },
  }), [formData, config, initialData]);

  // ===== 권한 계산 =====
  // config.permissions가 명시적으로 설정되면 우선, 아니면 usePermission() fallback
  const permissions = useMemo(() => {
    const p = config.permissions || {};
    return {
      canEdit: typeof p.canEdit === 'function' ? p.canEdit() : (p.canEdit !== undefined ? p.canEdit : permCanUpdate),
      canDelete: typeof p.canDelete === 'function' ? p.canDelete() : (p.canDelete !== undefined ? p.canDelete : permCanDelete),
      canCreate: typeof p.canCreate === 'function' ? p.canCreate() : (p.canCreate !== undefined ? p.canCreate : permCanCreate),
    };
  }, [config.permissions, permCanUpdate, permCanDelete, permCanCreate]);

  // ===== 모드 헬퍼 =====
  const isViewMode = mode === 'view';
  const isCreateMode = mode === 'create';
  const isEditMode = mode === 'edit';

  // ===== mode prop 변경 시 내부 state 동기화 =====
  useEffect(() => {
    setMode(initialMode);
  }, [initialMode]);

  // ===== 초기 데이터 설정 =====
  useEffect(() => {
    if (initialData) {
      const transformed = config.transformInitialData
        ? config.transformInitialData(initialData)
        : (initialData as Record<string, unknown>);
      setFormData(transformed);
    } else {
      // 기본값 설정 (field.defaultValue 우선 적용)
      const defaultData: Record<string, unknown> = {};
      config.fields.forEach((field) => {
        if (field.defaultValue !== undefined) {
          defaultData[field.key] = field.defaultValue;
        } else if (field.type === 'checkbox') {
          defaultData[field.key] = false;
        } else {
          defaultData[field.key] = '';
        }
      });
      setFormData(defaultData);
    }
  }, [initialData, config.transformInitialData, config.fields]);

  // ===== 동적 옵션 로드 =====
  useEffect(() => {
    const loadDynamicOptions = async () => {
      const optionsToLoad = config.fields.filter((f) => f.fetchOptions);
      const results: Record<string, FieldOption[]> = {};

      await Promise.all(
        optionsToLoad.map(async (field) => {
          try {
            const options = await field.fetchOptions!();
            results[field.key] = options;
          } catch (error) {
            console.error(`Failed to load options for ${field.key}:`, error);
            results[field.key] = [];
          }
        })
      );

      setDynamicOptions(results);
    };

    loadDynamicOptions();
  }, [config.fields]);

  // ===== 필드 변경 핸들러 =====
  const handleChange = useCallback((key: string, value: unknown) => {
    setFormData((prev) => ({ ...prev, [key]: value }));
    // 에러 클리어
    if (errors[key]) {
      setErrors((prev) => {
        const next = { ...prev };
        delete next[key];
        return next;
      });
    }
  }, [errors]);

  // ===== 유효성 검사 =====
  const validate = useCallback((): boolean => {
    const newErrors: Record<string, string> = {};

    config.fields.forEach((field) => {
      const value = formData[field.key];

      // 필수 검사
      if (field.required) {
        if (value === null || value === undefined || value === '') {
          newErrors[field.key] = `${field.label}은(는) 필수입니다.`;
          return;
        }
      }

      // 커스텀 유효성 검사
      if (field.validation) {
        for (const rule of field.validation) {
          if (!validateRule(rule, value, formData)) {
            newErrors[field.key] = rule.message;
            break;
          }
        }
      }
    });

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  }, [config.fields, formData]);

  // ===== 네비게이션 =====
  const navigateToList = useCallback(() => {
    router.push(`/${locale}${config.basePath}`);
  }, [router, locale, config.basePath]);

  // ===== 취소 핸들러 =====
  const handleCancel = useCallback(() => {
    if (onCancel) {
      onCancel();
    } else if (isCreateMode) {
      navigateToList();
    } else {
      setMode('view');
      // 원래 데이터로 복원
      if (initialData) {
        const transformed = config.transformInitialData
          ? config.transformInitialData(initialData)
          : (initialData as Record<string, unknown>);
        setFormData(transformed);
      }
      setErrors({});
      // URL도 view 모드로 변경 (handleEdit와 대칭)
      if (itemId) {
        router.push(`/${locale}${config.basePath}/${itemId}?mode=view`);
      }
    }
  }, [onCancel, isCreateMode, navigateToList, initialData, config.transformInitialData, itemId, router, locale, config.basePath]);

  // ===== 제출 핸들러 =====
  const handleSubmit = useCallback(async () => {
    if (!validate()) {
      toast.error('입력 정보를 확인해주세요.');
      return;
    }

    if (!onSubmit) {
      toast.error('저장 핸들러가 설정되지 않았습니다.');
      return;
    }

    setIsSubmitting(true);
    try {
      const dataToSubmit = config.transformSubmitData
        ? config.transformSubmitData(formData)
        : formData;

      const result = await onSubmit(dataToSubmit);
      if (result?.success) {
        toast.success(isCreateMode ? '등록되었습니다.' : '저장되었습니다.');
        navigateToList();
      } else if (result?.error !== '') {
        // error가 빈 문자열이면 토스트 표시 안 함 (커스텀 네비게이션 처리용)
        toast.error(result?.error || '저장에 실패했습니다.');
      }
    } catch (error) {
      console.error('Submit error:', error);
      toast.error('저장 중 오류가 발생했습니다.');
    } finally {
      setIsSubmitting(false);
    }
  }, [validate, onSubmit, config.transformSubmitData, formData, isCreateMode, navigateToList]);

  // ===== 삭제 핸들러 =====
  const handleDelete = useCallback(() => {
    setShowDeleteDialog(true);
  }, []);

  const handleConfirmDelete = useCallback(async () => {
    if (!onDelete || !itemId) {
      toast.error('삭제 핸들러가 설정되지 않았습니다.');
      return;
    }

    setIsSubmitting(true);
    try {
      const result = await onDelete(itemId);
      if (result?.success) {
        toast.success('삭제되었습니다.');
        navigateToList();
      } else {
        toast.error(result?.error || '삭제에 실패했습니다.');
      }
    } catch (error) {
      console.error('Delete error:', error);
      toast.error('삭제 중 오류가 발생했습니다.');
    } finally {
      setIsSubmitting(false);
      setShowDeleteDialog(false);
    }
  }, [onDelete, itemId, navigateToList]);

  // ===== 수정 모드 전환 =====
  const handleEdit = useCallback(() => {
    // 커스텀 onEdit이 제공되면 해당 핸들러 사용 (예: 페이지 이동)
    if (onEditProp) {
      onEditProp();
      return;
    }
    // 기본 동작: 내부 모드 변경 + URL 변경
    setMode('edit');
    onModeChange?.('edit');
    // URL에 ?mode=edit 추가
    if (itemId) {
      router.push(`/${locale}${config.basePath}/${itemId}?mode=edit`);
    }
  }, [onEditProp, onModeChange, router, locale, config.basePath, itemId]);

  // ===== 액션 설정 =====
  const actions = config.actions || {};
  const deleteConfirm = {
    title: actions.deleteConfirmMessage?.title || '삭제 확인',
    description: actions.deleteConfirmMessage?.description || '이 항목을 삭제하시겠습니까?',
  };

  // ===== 버튼 위치 =====
  const isTopButtons = buttonPosition === 'top';

  // ===== 액션 버튼 렌더링 헬퍼 =====
  // sticky는 하단 배치(buttonPosition='bottom')일 때만 적용
  const shouldSticky = stickyButtons && !isTopButtons;

  const renderActionButtons = useCallback((additionalClass?: string) => {
    if (actions.hideActions) return null;
    return (
      <DetailActions
        mode={mode}
        isSubmitting={isSubmitting}
        permissions={permissions}
        showButtons={{
          back: actions.showBack !== false,
          delete: actions.showDelete !== false && !!onDelete,
          edit: actions.showEdit !== false,
          save: actions.showSave !== false,
        }}
        labels={{
          back: actions.backLabel,
          cancel: actions.cancelLabel,
          delete: actions.deleteLabel,
          edit: actions.editLabel,
          submit: actions.submitLabel,
        }}
        onBack={navigateToList}
        onCancel={handleCancel}
        onDelete={handleDelete}
        onEdit={handleEdit}
        onSubmit={handleSubmit}
        extraActions={headerActions}
        extraActionItems={headerActionItems}
        sticky={shouldSticky}
        className={additionalClass}
      />
    );
  }, [
    mode, isSubmitting, permissions, actions, headerActions, headerActionItems, shouldSticky,
    navigateToList, handleDelete, handleEdit, handleCancel, handleSubmit, onDelete
  ]);

  // ===== 필터링된 필드 =====
  const visibleFields = useMemo(() => {
    return config.fields.filter((field) => {
      if (isViewMode && field.hideInView) return false;
      if (!isViewMode && field.hideInForm) return false;
      return true;
    });
  }, [config.fields, isViewMode]);

  // ===== 그리드 컬럼 수 =====
  const gridCols = config.gridColumns || 2;

  // ===== 로딩 상태 =====
  if (isLoading) {
    return (
      <PageLayout>
        <PageHeader
          title={config.title}
          description={config.description}
          icon={config.icon}
          actions={isTopButtons ? renderActionButtons() : undefined}
        />
        <DetailSectionSkeleton cols={gridCols} fieldCount={6} />
        {!isTopButtons && renderActionButtons('mt-6')}
      </PageLayout>
    );
  }

  // ===== View 모드 - 커스텀 렌더러 =====
  if (isViewMode && renderView && initialData) {
    return (
      <PageLayout>
        <PageHeader
          title={config.title}
          description={config.description}
          icon={config.icon}
          actions={isTopButtons ? renderActionButtons() : undefined}
        />
        <div className={shouldSticky ? 'pb-24' : ''}>
          {beforeContent}
          {renderView(initialData)}
          {afterContent}
        </div>
        {/* 버튼 영역 - 하단 배치 시만 */}
        {!isTopButtons && renderActionButtons('mt-6')}
        <DeleteConfirmDialog
          open={showDeleteDialog}
          onOpenChange={setShowDeleteDialog}
          onConfirm={handleConfirmDelete}
          title={deleteConfirm.title}
          description={deleteConfirm.description}
        />
      </PageLayout>
    );
  }

  // ===== Form 모드 - 커스텀 렌더러 =====
  // View 모드에서 renderView가 없으면 renderForm으로 폴백 (EmployeeForm 등 renderForm만 사용하는 컴포넌트 지원)
  if (renderForm && (!isViewMode || !renderView)) {
    return (
      <PageLayout>
        <PageHeader
          title={isCreateMode ? `${config.title} 등록` : isViewMode ? config.title : `${config.title} 수정`}
          description={config.description}
          icon={config.icon}
          actions={isTopButtons ? renderActionButtons() : undefined}
        />
        <div className={shouldSticky ? 'pb-24' : ''}>
          {beforeContent}
          {renderForm({
            formData,
            onChange: handleChange,
            mode,
            errors,
          })}
          {afterContent}
        </div>
        {/* 버튼 영역 - 하단 배치 시만 */}
        {!isTopButtons && renderActionButtons('mt-6')}
        {/* View 모드에서 renderForm 폴백 시 삭제 다이얼로그 필요 */}
        {isViewMode && (
          <DeleteConfirmDialog
            open={showDeleteDialog}
            onOpenChange={setShowDeleteDialog}
            onConfirm={handleConfirmDelete}
            title={deleteConfirm.title}
            description={deleteConfirm.description}
          />
        )}
      </PageLayout>
    );
  }

  // ===== 기본 렌더링 =====
  return (
    <PageLayout>
      <PageHeader
        title={
          isCreateMode
            ? `${config.title} 등록`
            : isEditMode
            ? `${config.title} 수정`
            : config.title
        }
        description={config.description}
        icon={config.icon}
        actions={isTopButtons ? renderActionButtons() : undefined}
      />

      <div className={`space-y-6 ${shouldSticky ? 'pb-24' : ''}`}>
        {beforeContent}

        {/* 섹션이 있으면 섹션별로, 없으면 단일 카드 */}
        {config.sections && config.sections.length > 0 ? (
          config.sections.map((section) => (
            <DetailSection
              key={section.id}
              title={section.title}
              description={section.description}
              collapsible={section.collapsible}
              defaultOpen={!section.defaultCollapsed}
            >
              <DetailGrid cols={gridCols}>
                {section.fields.map((fieldKey) => {
                  const field = visibleFields.find((f) => f.key === fieldKey);
                  if (!field) return null;
                  return renderFieldItem(field);
                })}
              </DetailGrid>
            </DetailSection>
          ))
        ) : (
          <DetailSection title="기본 정보">
            <DetailGrid cols={gridCols}>
              {visibleFields.map((field) => renderFieldItem(field))}
            </DetailGrid>
          </DetailSection>
        )}

        {afterContent}

        {/* 버튼 영역 - 하단 배치 시만 */}
        {!isTopButtons && renderActionButtons()}
      </div>

      {/* 삭제 확인 다이얼로그 */}
      <DeleteConfirmDialog
        open={showDeleteDialog}
        onOpenChange={setShowDeleteDialog}
        onConfirm={handleConfirmDelete}
        title={deleteConfirm.title}
        description={deleteConfirm.description}
      />
    </PageLayout>
  );

  // ===== 필드 아이템 렌더링 헬퍼 =====
  function renderFieldItem(field: FieldDefinition) {
    // gridSpan을 colSpan으로 매핑 (1, 2, 3, 4만 허용)
    const colSpan = (field.gridSpan || 1) as 1 | 2 | 3 | 4;

    // 커스텀 필드 렌더러 체크
    if (renderField) {
      const customRender = renderField(field, {
        value: formData[field.key],
        onChange: (value: unknown) => handleChange(field.key, value),
        mode,
        disabled:
          field.readonly ||
          (typeof field.disabled === 'function' ? field.disabled(mode) : !!field.disabled),
        error: errors[field.key],
      });
      if (customRender !== null) {
        return (
          <DetailField
            key={field.key}
            label={field.label}
            required={field.required}
            error={errors[field.key]}
            description={field.helpText}
            colSpan={colSpan}
            htmlFor={field.key}
            mode={mode}
          >
            {customRender}
          </DetailField>
        );
      }
    }

    return (
      <DetailField
        key={field.key}
        label={field.label}
        required={field.required}
        error={errors[field.key]}
        description={field.helpText}
        colSpan={colSpan}
        htmlFor={field.key}
        mode={mode}
      >
        <FieldInput
          field={field}
          value={formData[field.key]}
          onChange={(value) => handleChange(field.key, value)}
          mode={mode}
          error={errors[field.key]}
          dynamicOptions={dynamicOptions[field.key]}
        />
      </DetailField>
    );
  }
}

// forwardRef wrapper with generic support
export const IntegratedDetailTemplate = forwardRef(IntegratedDetailTemplateInner) as <
  T extends Record<string, unknown>
>(
  props: IntegratedDetailTemplateProps<T> & { ref?: React.ForwardedRef<IntegratedDetailTemplateRef> }
) => React.ReactElement;

// ===== 유효성 검사 헬퍼 =====
function validateRule(
  rule: ValidationRule,
  value: unknown,
  formData: Record<string, unknown>
): boolean {
  const strValue = value !== null && value !== undefined ? String(value) : '';

  switch (rule.type) {
    case 'required':
      return strValue.trim().length > 0;

    case 'minLength':
      return strValue.length >= (rule.value as number);

    case 'maxLength':
      return strValue.length <= (rule.value as number);

    case 'pattern':
      return new RegExp(rule.value as string).test(strValue);

    case 'custom':
      return rule.validate ? rule.validate(value, formData) : true;

    default:
      return true;
  }
}

// Re-export types
export * from './types';

// Re-export FieldInput
export { FieldInput, type FieldInputProps } from './FieldInput';

// Re-export internal components
export {
  DetailSection,
  DetailGrid,
  DetailField,
  DetailActions,
  DetailFieldSkeleton,
  DetailGridSkeleton,
  DetailSectionSkeleton,
  type DetailSectionProps,
  type DetailGridProps,
  type DetailFieldProps,
  type DetailActionsProps,
  type DetailFieldSkeletonProps,
  type DetailGridSkeletonProps,
  type DetailSectionSkeletonProps,
} from './components';
