'use client';

import React, { useEffect, useMemo, useRef, useState, useTransition } from 'react';
import { Dialog } from '@alga-psa/ui/components/Dialog';
import { WizardProgress } from '@alga-psa/ui/components/onboarding/WizardProgress';
import { WizardNavigation } from '@alga-psa/ui/components/onboarding/WizardNavigation';
import { ConfirmationDialog } from '@alga-psa/ui/components/ConfirmationDialog';
import { ContractBasicsStep } from './wizard-steps/ContractBasicsStep';
import { FixedFeeServicesStep } from './wizard-steps/FixedFeeServicesStep';
import { ProductsStep } from './wizard-steps/ProductsStep';
import { HourlyServicesStep } from './wizard-steps/HourlyServicesStep';
import { UsageBasedServicesStep } from './wizard-steps/UsageBasedServicesStep';
import { ReviewContractStep } from './wizard-steps/ReviewContractStep';
import {
  createClientContractFromWizard,
  listContractTemplatesForWizard,
  getContractTemplateSnapshotForClientWizard,
  ClientContractWizardSubmission,
  ClientTemplateSnapshot,
} from '@alga-psa/billing/actions/contractWizardActions';
import { getDefaultBillingSettings } from '@alga-psa/billing/actions/billingSettingsActions';
import { handleError, isActionPermissionError } from '@alga-psa/ui/lib/errorHandling';
import {
  getUnsupportedRecurringAuthoringCombination,
  getUnsupportedRecurringAuthoringCombinationMessage,
} from '@shared/billingClients/recurringAuthoringValidation';
import { useTranslation } from '@alga-psa/ui/lib/i18n/client';

const REQUIRED_STEPS = [0, 5];
const MIN_NOTICE_PERIOD_DAYS = 0;
const MAX_NOTICE_PERIOD_DAYS = 3650;
const HARD_DEFAULT_RENEWAL_MODE: NonNullable<ContractWizardData['renewal_mode']> = 'manual';
const HARD_DEFAULT_NOTICE_PERIOD_DAYS = 30;
const RECURRING_LINE_TYPE_KEYS = {
  Fixed: 'fixed',
  Product: 'product',
  Hourly: 'hourly',
  Usage: 'usage',
} as const;

function isEqual(a: unknown, b: unknown): boolean {
  if (a === b) return true;
  if (a === null || b === null || a === undefined || b === undefined) return a === b;
  if (typeof a !== typeof b) return false;

  if (Array.isArray(a) && Array.isArray(b)) {
    if (a.length !== b.length) return false;
    for (let i = 0; i < a.length; i++) {
      if (!isEqual(a[i], b[i])) return false;
    }
    return true;
  }

  if (typeof a === 'object' && typeof b === 'object') {
    const objA = a as Record<string, unknown>;
    const objB = b as Record<string, unknown>;
    const keysA = Object.keys(objA);
    const keysB = Object.keys(objB);
    if (keysA.length !== keysB.length) return false;
    for (const key of keysA) {
      if (!Object.prototype.hasOwnProperty.call(objB, key)) return false;
      if (!isEqual(objA[key], objB[key])) return false;
    }
    return true;
  }

  return false;
}

function deepClone<T>(value: T): T {
  if (value === null || value === undefined) return value;
  if (Array.isArray(value)) return value.map((item) => deepClone(item)) as T;
  if (typeof value === 'object') {
    const obj = value as Record<string, unknown>;
    const cloned: Record<string, unknown> = {};
    for (const key of Object.keys(obj)) {
      cloned[key] = deepClone(obj[key]);
    }
    return cloned as T;
  }
  return value;
}

export interface BucketOverlayInput {
  total_minutes?: number;
  overage_rate?: number;
  allow_rollover?: boolean;
  billing_period?: 'monthly' | 'weekly';
}

export interface ContractWizardData {
  client_id: string;
  contract_name: string;
  start_date: string;
  end_date?: string;
  renewal_mode?: 'none' | 'manual' | 'auto';
  notice_period_days?: number;
  renewal_term_months?: number;
  use_tenant_renewal_defaults?: boolean;
  description?: string;
  cadence_owner?: 'client' | 'contract';
  billing_timing?: 'arrears' | 'advance';
  billing_frequency: string;
  currency_code: string;
  po_number?: string;
  po_amount?: number;
  po_required?: boolean;
  fixed_services: Array<{
    service_id: string;
    service_name?: string;
    quantity: number;
    bucket_overlay?: BucketOverlayInput | null;
  }>;
  product_services: Array<{
    service_id: string;
    service_name?: string;
    quantity: number;
    /** Optional per-unit override in cents (contract currency). */
    custom_rate?: number;
  }>;
  fixed_base_rate?: number;
  fixed_billing_frequency?: string;
  enable_proration: boolean;
  hourly_services: Array<{
    service_id: string;
    service_name?: string;
    hourly_rate?: number;
    bucket_overlay?: BucketOverlayInput | null;
  }>;
  hourly_billing_frequency?: string;
  minimum_billable_time?: number;
  round_up_to_nearest?: number;
  usage_services?: Array<{
    service_id: string;
    service_name?: string;
    unit_rate?: number;
    unit_of_measure?: string;
    bucket_overlay?: BucketOverlayInput | null;
  }>;
  usage_billing_frequency?: string;
  contract_id?: string;
  is_draft?: boolean;
  template_id?: string;
}

export const createDefaultContractWizardData = (): ContractWizardData => ({
  client_id: '',
  contract_name: '',
  start_date: '',
  end_date: undefined,
  renewal_mode: 'manual',
  notice_period_days: 30,
  renewal_term_months: undefined,
  use_tenant_renewal_defaults: true,
  description: '',
  cadence_owner: 'client',
  billing_timing: 'arrears',
  billing_frequency: 'monthly',
  currency_code: 'USD',
  fixed_services: [],
  product_services: [],
  fixed_base_rate: undefined,
  enable_proration: true,
  hourly_services: [],
  minimum_billable_time: undefined,
  round_up_to_nearest: undefined,
  usage_services: [],
  template_id: undefined,
});

const normalizeRenewalMode = (value: unknown): ContractWizardData['renewal_mode'] | undefined => {
  return value === 'none' || value === 'manual' || value === 'auto' ? value : undefined;
};

const normalizeNonNegativeInteger = (value: unknown): number | undefined => {
  if (value === null || value === undefined) return undefined;
  const numeric = typeof value === 'string' ? Number(value) : value;
  if (typeof numeric !== 'number' || !Number.isFinite(numeric)) return undefined;
  return Math.max(0, Math.trunc(numeric));
};

const normalizePositiveInteger = (value: unknown): number | undefined => {
  const normalized = normalizeNonNegativeInteger(value);
  return normalized && normalized > 0 ? normalized : undefined;
};

export const buildInitialContractWizardData = (
  editingContract: ContractWizardData | null = null
): ContractWizardData => {
  const initial: ContractWizardData = {
    ...createDefaultContractWizardData(),
    ...(editingContract ?? {}),
  };

  const renewalMode = normalizeRenewalMode(editingContract?.renewal_mode);
  const noticePeriodDays = normalizeNonNegativeInteger(editingContract?.notice_period_days);
  const renewalTermMonths = normalizePositiveInteger(editingContract?.renewal_term_months);

  if (renewalMode !== undefined) {
    initial.renewal_mode = renewalMode;
  }
  if (noticePeriodDays !== undefined) {
    initial.notice_period_days = noticePeriodDays;
  }
  if (renewalTermMonths !== undefined) {
    initial.renewal_term_months = renewalTermMonths;
  }
  if (typeof editingContract?.use_tenant_renewal_defaults === 'boolean') {
    initial.use_tenant_renewal_defaults = editingContract.use_tenant_renewal_defaults;
  }

  return initial;
};

type TemplateOption = {
  contract_id: string;
  contract_name: string;
  contract_description?: string | null;
  billing_frequency?: string | null;
};

interface ContractWizardProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onComplete?: (data: ContractWizardData) => void;
  editingContract?: ContractWizardData | null;
  initialClientId?: string;
}

export function ContractWizard({
  open,
  onOpenChange,
  onComplete,
  editingContract = null,
  initialClientId,
}: ContractWizardProps) {
  const { t } = useTranslation('msp/contracts');
  const initialWizardDataRef = useRef<ContractWizardData | null>(null);
  const [currentStep, setCurrentStep] = useState(0);
  const [isLoading, setIsLoading] = useState(false);
  const [errors, setErrors] = useState<Record<number, string>>({});
  const [completedSteps, setCompletedSteps] = useState<Set<number>>(new Set());
  const [showUnsavedChangesDialog, setShowUnsavedChangesDialog] = useState(false);

  const [templates, setTemplates] = useState<TemplateOption[]>([]);
  const [isLoadingTemplates, setIsLoadingTemplates] = useState(false);
  const [selectedTemplateId, setSelectedTemplateId] = useState<string | null>(null);
  const [templateError, setTemplateError] = useState<string | null>(null);
  const [isTemplateLoading, startTemplateTransition] = useTransition();

  const [wizardData, setWizardData] = useState<ContractWizardData>(() => ({
    ...buildInitialContractWizardData(editingContract),
  }));
  const formatList = useMemo(
    () => new Intl.ListFormat(undefined, { style: 'long', type: 'conjunction' }),
    []
  );

  const stepLabels = useMemo(
    () => ([
      t('wizard.steps.contractBasics', { defaultValue: 'Contract Basics' }),
      t('wizard.steps.fixedFeeServices', { defaultValue: 'Fixed Fee Services' }),
      t('wizard.steps.products', { defaultValue: 'Products' }),
      t('wizard.steps.hourlyServices', { defaultValue: 'Hourly Services' }),
      t('wizard.steps.usageBasedServices', { defaultValue: 'Usage-Based Services' }),
      t('wizard.steps.reviewCreate', { defaultValue: 'Review & Create' }),
    ]),
    [t]
  );

  useEffect(() => {
    if (!open) {
      initialWizardDataRef.current = null;
      setShowUnsavedChangesDialog(false);
      resetWizard();
      return;
    }

    setErrors({});
    setCompletedSteps(new Set());
    setCurrentStep(0);

    const initialWizardData = buildInitialContractWizardData(editingContract);
    if (!editingContract && initialClientId) {
      initialWizardData.client_id = initialClientId;
    }
    initialWizardDataRef.current = deepClone(initialWizardData);

    if (editingContract) {
      setWizardData(initialWizardData);
      setSelectedTemplateId(editingContract.template_id ?? null);
    } else {
      setWizardData(initialWizardData);
      setSelectedTemplateId(null);
    }

    setIsLoadingTemplates(true);
    setTemplateError(null);
    listContractTemplatesForWizard()
      .then((options) => {
        setTemplates(options);
      })
      .catch((error) => {
        console.error('Failed to load contract templates', error);
        setTemplateError(
          t('wizard.errors.failedToLoadTemplates', { defaultValue: 'Failed to load templates' })
        );
      })
      .finally(() => {
        setIsLoadingTemplates(false);
      });

    // Apply tenant default currency for new contracts
    if (!editingContract) {
      getDefaultBillingSettings()
        .then((settings) => {
          const currency = settings.defaultCurrencyCode || 'USD';
          setWizardData((prev) => ({
            ...prev,
            currency_code: currency,
          }));
        })
        .catch(() => {});
    }
  }, [open, editingContract, initialClientId, t]);

  const resetWizard = () => {
    setWizardData(createDefaultContractWizardData());
    setSelectedTemplateId(null);
    setErrors({});
    setCompletedSteps(new Set());
    setCurrentStep(0);
  };

  const updateData = (data: Partial<ContractWizardData>) => {
    setWizardData((prev) => ({ ...prev, ...data }));
  };

  const hasUnsavedChanges = useMemo(() => {
    if (!open) return false;
    if (!initialWizardDataRef.current) return false;
    return !isEqual(wizardData, initialWizardDataRef.current);
  }, [open, wizardData]);

  const handleCloseRequest = () => {
    if (hasUnsavedChanges) {
      setShowUnsavedChangesDialog(true);
      return;
    }
    onOpenChange(false);
  };

  const applyTemplateSnapshot = (snapshot: ClientTemplateSnapshot, templateId: string) => {
    setWizardData((prev) => ({
      ...prev,
      template_id: templateId,
      contract_name: snapshot.contract_name ?? prev.contract_name,
      description: snapshot.description ?? prev.description,
      billing_frequency: snapshot.billing_frequency ?? prev.billing_frequency,
      cadence_owner: snapshot.cadence_owner ?? prev.cadence_owner,
      billing_timing: snapshot.billing_timing ?? prev.billing_timing,
      // currency_code is inherited from client, not from template (templates are currency-neutral)
      fixed_services: snapshot.fixed_services ?? [],
      product_services: snapshot.product_services ?? [],
      fixed_base_rate: snapshot.fixed_base_rate,
      enable_proration: snapshot.enable_proration ?? prev.enable_proration,
      hourly_services: snapshot.hourly_services ?? [],
      usage_services: snapshot.usage_services ?? [],
      minimum_billable_time: snapshot.minimum_billable_time ?? prev.minimum_billable_time,
      round_up_to_nearest: snapshot.round_up_to_nearest ?? prev.round_up_to_nearest,
    }));
  };

  const handleTemplateSelect = (templateId: string | null) => {
    setSelectedTemplateId(templateId);
    if (!templateId) {
      setTemplateError(null);
      updateData({ template_id: undefined });
      return;
    }

    setTemplateError(null);
    startTemplateTransition(async () => {
      try {
        const snapshot = await getContractTemplateSnapshotForClientWizard(templateId);
        applyTemplateSnapshot(snapshot, templateId);
      } catch (error) {
        console.error('Failed to load template snapshot', error);
        setTemplateError(
          t('wizard.errors.failedToLoadTemplateDetails', { defaultValue: 'Failed to load template details' })
        );
      }
    });
  };

  const buildSubmissionData = async (): Promise<ClientContractWizardSubmission> => {
    const useTenantDefaults = wizardData.use_tenant_renewal_defaults ?? true;

    let tenantDefaultRenewalMode: ContractWizardData['renewal_mode'] | undefined;
    let tenantDefaultNoticePeriodDays: number | undefined;

    try {
      const tenantDefaults = await getDefaultBillingSettings();
      tenantDefaultRenewalMode = tenantDefaults.defaultRenewalMode;
      tenantDefaultNoticePeriodDays = tenantDefaults.defaultNoticePeriodDays;
    } catch (error) {
      console.warn('Failed to load tenant renewal defaults for wizard submission', error);
    }

    const resolvedRenewalMode: NonNullable<ContractWizardData['renewal_mode']> = useTenantDefaults
      ? tenantDefaultRenewalMode ?? HARD_DEFAULT_RENEWAL_MODE
      : wizardData.renewal_mode ?? tenantDefaultRenewalMode ?? HARD_DEFAULT_RENEWAL_MODE;

    const resolvedNoticePeriodDays = useTenantDefaults
      ? tenantDefaultNoticePeriodDays ?? HARD_DEFAULT_NOTICE_PERIOD_DAYS
      : wizardData.notice_period_days ??
        tenantDefaultNoticePeriodDays ??
        HARD_DEFAULT_NOTICE_PERIOD_DAYS;

    return {
      contract_id: wizardData.contract_id,
      contract_name: wizardData.contract_name.trim(),
      description: wizardData.description?.trim() || undefined,
      client_id: wizardData.client_id || '',
      start_date: wizardData.start_date,
      renewal_mode: resolvedRenewalMode,
      notice_period_days: resolvedNoticePeriodDays,
      renewal_term_months: wizardData.renewal_term_months,
      use_tenant_renewal_defaults: useTenantDefaults,
      cadence_owner: wizardData.cadence_owner ?? 'client',
      billing_timing: wizardData.billing_timing ?? 'arrears',
      end_date: wizardData.end_date,
      po_required: wizardData.po_required,
      po_number: wizardData.po_number,
      po_amount: wizardData.po_amount,
      fixed_base_rate: wizardData.fixed_base_rate,
      fixed_billing_frequency: wizardData.fixed_billing_frequency,
      enable_proration: wizardData.enable_proration,
      hourly_services: wizardData.hourly_services ?? [],
      hourly_billing_frequency: wizardData.hourly_billing_frequency,
      fixed_services: wizardData.fixed_services ?? [],
      product_services: wizardData.product_services ?? [],
      usage_services: wizardData.usage_services ?? [],
      usage_billing_frequency: wizardData.usage_billing_frequency,
      minimum_billable_time: wizardData.minimum_billable_time,
      round_up_to_nearest: wizardData.round_up_to_nearest,
      billing_frequency: wizardData.billing_frequency,
      currency_code: wizardData.currency_code,
      template_id: wizardData.template_id,
    };
  };

  const getRecurringAuthoringValidationError = (): string | null => {
    const unsupportedCombination = [
      wizardData.fixed_services.length > 0
        ? getUnsupportedRecurringAuthoringCombination({
            lineType: 'Fixed',
            cadenceOwner: wizardData.cadence_owner,
            billingTiming: wizardData.billing_timing,
            billingFrequency: wizardData.fixed_billing_frequency ?? wizardData.billing_frequency,
          })
        : null,
      wizardData.product_services.length > 0
        ? getUnsupportedRecurringAuthoringCombination({
            lineType: 'Product',
            cadenceOwner: wizardData.cadence_owner,
            billingTiming: wizardData.billing_timing,
            billingFrequency: wizardData.billing_frequency,
          })
        : null,
      wizardData.hourly_services.length > 0
        ? getUnsupportedRecurringAuthoringCombination({
            lineType: 'Hourly',
            cadenceOwner: wizardData.cadence_owner,
            billingTiming: wizardData.billing_timing,
            billingFrequency: wizardData.hourly_billing_frequency ?? wizardData.billing_frequency,
          })
        : null,
      (wizardData.usage_services?.length ?? 0) > 0
        ? getUnsupportedRecurringAuthoringCombination({
            lineType: 'Usage',
            cadenceOwner: wizardData.cadence_owner,
            billingTiming: wizardData.billing_timing,
            billingFrequency: wizardData.usage_billing_frequency ?? wizardData.billing_frequency,
          })
        : null,
    ].find((combination) => Boolean(combination));

    if (!unsupportedCombination) {
      return null;
    }

    const supportedFrequencies = unsupportedCombination.supportedBillingFrequencies.map((value) =>
      t(`wizard.validation.recurring.frequency.${value}`, { defaultValue: value })
    );
    const recurringLineType = t(
      `wizard.validation.recurring.lineType.${RECURRING_LINE_TYPE_KEYS[unsupportedCombination.lineType]}`,
      { defaultValue: unsupportedCombination.lineType }
    );
    const unsupportedFrequency = t(
      `wizard.validation.recurring.frequency.${unsupportedCombination.billingFrequency}`,
      { defaultValue: unsupportedCombination.billingFrequency }
    );
    const defaultRecurringMessage = getUnsupportedRecurringAuthoringCombinationMessage({
      lineType: unsupportedCombination.lineType,
      cadenceOwner: 'contract',
      billingTiming: wizardData.billing_timing,
      billingFrequency: unsupportedCombination.billingFrequency,
    });

    return t('wizard.validation.unsupportedRecurringAuthoringCombination', {
      defaultValue:
        defaultRecurringMessage ??
        'Unsupported recurring authoring combination for {{lineType}} services: contract anniversary cadence currently supports {{supportedFrequencies}} billing frequencies. {{billingFrequency}} is not supported yet. Use one of the supported frequencies or invoice on the client billing schedule instead.',
      lineType: recurringLineType,
      supportedFrequencies: formatList.format(supportedFrequencies),
      billingFrequency: unsupportedFrequency,
    });
  };

  const validateStep = (stepIndex: number): boolean => {
    setErrors((prev) => ({ ...prev, [stepIndex]: '' }));

    switch (stepIndex) {
      case 0:
        if (!wizardData.client_id) {
          setErrors((prev) => ({
            ...prev,
            [stepIndex]: t('wizard.validation.clientRequired', { defaultValue: 'Client is required' }),
          }));
          return false;
        }
        if (!wizardData.contract_name?.trim()) {
          setErrors((prev) => ({
            ...prev,
            [stepIndex]: t('wizard.validation.contractNameRequired', { defaultValue: 'Contract name is required' }),
          }));
          return false;
        }
        if (!wizardData.billing_frequency) {
          setErrors((prev) => ({
            ...prev,
            [stepIndex]: t('wizard.validation.billingFrequencyRequired', { defaultValue: 'Billing frequency is required' }),
          }));
          return false;
        }
        if (!wizardData.start_date) {
          setErrors((prev) => ({
            ...prev,
            [stepIndex]: t('wizard.validation.startDateRequired', { defaultValue: 'Start date is required' }),
          }));
          return false;
        }
        if (wizardData.end_date && !wizardData.renewal_mode) {
          setErrors((prev) => ({
            ...prev,
            [stepIndex]: t('wizard.validation.renewalModeRequiredWithEndDate', {
              defaultValue: 'Renewal mode is required when an end date is set',
            }),
          }));
          return false;
        }
        if (wizardData.renewal_mode && wizardData.renewal_mode !== 'none') {
          if (!Number.isInteger(wizardData.notice_period_days)) {
            setErrors((prev) => ({
              ...prev,
              [stepIndex]: t('wizard.validation.noticePeriodWholeNumber', {
                defaultValue: 'Notice period must be a whole number of days',
              }),
            }));
            return false;
          }

          const noticePeriod = wizardData.notice_period_days as number;
          if (noticePeriod < MIN_NOTICE_PERIOD_DAYS || noticePeriod > MAX_NOTICE_PERIOD_DAYS) {
            setErrors((prev) => ({
              ...prev,
              [stepIndex]: t('wizard.validation.noticePeriodRange', {
                defaultValue: 'Notice period must be between {{min}} and {{max}} days',
                min: MIN_NOTICE_PERIOD_DAYS,
                max: MAX_NOTICE_PERIOD_DAYS,
              }),
            }));
            return false;
          }
        }
        if (wizardData.renewal_term_months !== undefined && wizardData.renewal_term_months !== null) {
          if (
            !Number.isInteger(wizardData.renewal_term_months) ||
            wizardData.renewal_term_months <= 0
          ) {
            setErrors((prev) => ({
              ...prev,
              [stepIndex]: t('wizard.validation.renewalTermPositiveWhole', {
                defaultValue: 'Renewal term months must be a positive whole number',
              }),
            }));
            return false;
          }
        }
        return true;
      case 1:
        if (wizardData.fixed_services.length > 0 && !wizardData.fixed_base_rate) {
          setErrors((prev) => ({
            ...prev,
            [stepIndex]: t('wizard.validation.baseRateRequiredWhenFixedServices', {
              defaultValue: 'Base rate is required when fixed services are included',
            }),
          }));
          return false;
        }
        return true;
      case 2: {
        const hasMissingProduct = (wizardData.product_services ?? []).some((p) => !p?.service_id);
        if (hasMissingProduct) {
          setErrors((prev) => ({
            ...prev,
            [stepIndex]: t('wizard.validation.selectProductForEachLine', {
              defaultValue: 'Please select a product for each product line',
            }),
          }));
          return false;
        }
        return true;
      }
      case 5: {
        const hasServices =
          wizardData.fixed_services.length > 0 ||
          wizardData.product_services.length > 0 ||
          wizardData.hourly_services.length > 0 ||
          !!(wizardData.usage_services && wizardData.usage_services.length > 0);
        if (!hasServices) {
          setErrors((prev) => ({
            ...prev,
            [stepIndex]: t('wizard.validation.addAtLeastOneService', {
              defaultValue: 'Add at least one service before creating the contract',
            }),
          }));
          return false;
        }
        const recurringAuthoringError = getRecurringAuthoringValidationError();
        if (recurringAuthoringError) {
          setErrors((prev) => ({
            ...prev,
            [stepIndex]: recurringAuthoringError,
          }));
          return false;
        }
        return true;
      }
      default:
        return true;
    }
  };

  const handleNext = () => {
    if (!validateStep(currentStep)) {
      return;
    }
    if (currentStep < stepLabels.length - 1) {
      setCompletedSteps((prev) => new Set([...prev, currentStep]));
      setCurrentStep((prev) => prev + 1);
    }
  };

  const handleBack = () => {
    if (currentStep > 0) {
      setCurrentStep((prev) => prev - 1);
    }
  };

  const handleSkip = () => {
    if (currentStep < stepLabels.length - 1 && !REQUIRED_STEPS.includes(currentStep)) {
      setCurrentStep((prev) => prev + 1);
    }
  };

  const handleStepClick = (stepIndex: number) => {
    if (
      stepIndex === 0 ||
      stepIndex === currentStep ||
      completedSteps.has(stepIndex) ||
      (stepIndex > 0 && completedSteps.has(stepIndex - 1))
    ) {
      setCurrentStep(stepIndex);
    }
  };

  const handleFinish = async () => {
    if (!validateStep(currentStep)) {
      return;
    }

    const recurringAuthoringError = getRecurringAuthoringValidationError();
    if (recurringAuthoringError) {
      setErrors((prev) => ({
        ...prev,
        [currentStep]: recurringAuthoringError,
      }));
      return;
    }

    setIsLoading(true);
    try {
      const submission = await buildSubmissionData();
      const result = await createClientContractFromWizard(submission);

      if (isActionPermissionError(result)) {
        handleError(result.permissionError);
        return;
      }

      const completedData: ContractWizardData = {
        ...wizardData,
        contract_id: result.contract_id,
      };

      setWizardData(completedData);
      onComplete?.(completedData);
      onOpenChange(false);
    } catch (error) {
      console.error('Error creating contract', error);
      setErrors((prev) => ({
        ...prev,
        [currentStep]: t('wizard.errors.failedToCreateContract', { defaultValue: 'Failed to create contract' }),
      }));
    } finally {
      setIsLoading(false);
    }
  };

  const handleSaveDraft = async () => {
    if (!validateStep(0)) {
      setCurrentStep(0);
      return;
    }

    if (!wizardData.client_id) {
      setErrors((prev) => ({
        ...prev,
        [currentStep]: t('wizard.validation.selectClientBeforeDraft', {
          defaultValue: 'Select a client before saving as draft',
        }),
      }));
      setCurrentStep(0);
      return;
    }

    const recurringAuthoringError = getRecurringAuthoringValidationError();
    if (recurringAuthoringError) {
      setErrors((prev) => ({
        ...prev,
        [currentStep]: recurringAuthoringError,
      }));
      return;
    }

    setIsLoading(true);
    try {
      const submission = await buildSubmissionData();
      const result = await createClientContractFromWizard(submission, { isDraft: true });

      if (isActionPermissionError(result)) {
        handleError(result.permissionError);
        return;
      }

      const draftData: ContractWizardData = {
        ...wizardData,
        contract_id: result.contract_id,
        client_id: wizardData.client_id || '',
        is_draft: true,
      };

      setWizardData(draftData);
      onComplete?.(draftData);
      onOpenChange(false);
    } catch (error) {
      console.error('Error saving contract draft', error);
      setErrors((prev) => ({
        ...prev,
        [currentStep]: t('wizard.errors.failedToSaveDraft', { defaultValue: 'Failed to save draft' }),
      }));
    } finally {
      setIsLoading(false);
    }
  };

  const renderStep = () => {
    switch (currentStep) {
      case 0:
        return (
          <ContractBasicsStep
            data={wizardData}
            updateData={updateData}
            templates={templates}
            isLoadingTemplates={isLoadingTemplates}
            selectedTemplateId={selectedTemplateId}
            onTemplateSelect={handleTemplateSelect}
            isTemplateLoading={isTemplateLoading}
            templateError={templateError}
          />
        );
      case 1:
        return <FixedFeeServicesStep data={wizardData} updateData={updateData} />;
      case 2:
        return <ProductsStep data={wizardData} updateData={updateData} />;
      case 3:
        return <HourlyServicesStep data={wizardData} updateData={updateData} />;
      case 4:
        return <UsageBasedServicesStep data={wizardData} updateData={updateData} />;
      case 5:
        return <ReviewContractStep data={wizardData} />;
      default:
        return null;
    }
  };

  const wizardFooter = (
    <WizardNavigation
      currentStep={currentStep}
      totalSteps={stepLabels.length}
      onBack={handleBack}
      onNext={handleNext}
      onSkip={handleSkip}
      onFinish={handleFinish}
      onSaveDraft={handleSaveDraft}
      isNextDisabled={isLoading}
      isSkipDisabled={REQUIRED_STEPS.includes(currentStep)}
      isLoading={isLoading}
      showSaveDraft
      backLabel={t('wizard.nav.back', { defaultValue: 'Back' })}
      nextLabel={t('wizard.nav.next', { defaultValue: 'Next' })}
      skipLabel={t('wizard.nav.skip', { defaultValue: 'Skip' })}
      finishLabel={t('wizard.nav.finish', { defaultValue: 'Finish Setup' })}
      saveDraftLabel={t('wizard.nav.saveDraft', { defaultValue: 'Save as Draft' })}
      savingLabel={t('wizard.nav.saving', { defaultValue: 'Saving...' })}
      completingLabel={t('wizard.nav.completing', { defaultValue: 'Completing...' })}
    />
  );

  return (
    <>
      <Dialog
        isOpen={open}
        onClose={handleCloseRequest}
        title={editingContract
          ? t('wizard.title.editContract', { defaultValue: 'Edit Contract' })
          : t('wizard.title.createNewContract', { defaultValue: 'Create New Contract' })}
        className="max-w-4xl max-h-[90vh]"
        disableFocusTrap
        footer={wizardFooter}
      >
        <div className="flex flex-col h-full">
          <div className="flex-shrink-0 px-6 pt-6">
            <WizardProgress
              steps={stepLabels as unknown as string[]}
              currentStep={currentStep}
              completedSteps={completedSteps}
              onStepClick={handleStepClick}
              canNavigateToStep={(stepIndex) =>
                stepIndex === 0 ||
                stepIndex === currentStep ||
                completedSteps.has(stepIndex) ||
                (stepIndex > 0 && completedSteps.has(stepIndex - 1))
              }
            />
          </div>

          <div className="flex-1 overflow-y-auto px-6 py-6">
            <div className="mb-4">{renderStep()}</div>

            {errors[currentStep] && (
              <div className="mb-4 p-3 bg-[rgb(var(--color-destructive)/0.1)] border border-[rgb(var(--color-destructive)/0.3)] rounded-md">
                <p className="text-[rgb(var(--color-destructive))] text-sm">{errors[currentStep]}</p>
              </div>
            )}
          </div>
        </div>
      </Dialog>

      <ConfirmationDialog
        id="contract-wizard-unsaved-changes"
        isOpen={showUnsavedChangesDialog}
        onClose={() => setShowUnsavedChangesDialog(false)}
        onConfirm={() => {
          setShowUnsavedChangesDialog(false);
          onOpenChange(false);
        }}
        title={t('wizard.dialogs.unsavedChanges.title', { defaultValue: 'Discard changes?' })}
        message={t('wizard.dialogs.unsavedChanges.message', {
          defaultValue: 'You have unsaved changes. If you close this dialog now, your changes will be discarded.',
        })}
        confirmLabel={t('wizard.dialogs.unsavedChanges.confirm', { defaultValue: 'Discard Changes' })}
        cancelLabel={t('wizard.dialogs.unsavedChanges.cancel', { defaultValue: 'Stay' })}
      />
    </>
  );
}
