import { supabase } from '@/lib/supabaseClient';
import type { Json } from '@/integrations/supabase/types';
import { uploadPendingImages } from './imageUploadHelper';
import { CompanyFormData, TempCompanyData } from '@/types/company';
import { handleError } from './errorHandler';
import { withRetry, isRetryableError } from './retryHelpers';
import { logger } from './logger';

export type { CompanyFormData, TempCompanyData };

export async function submitCompanyCreation(
  data: CompanyFormData, 
  companyType: 'manufacturer' | 'designer' | 'operator' | 'property_owner',
  userId: string
) {
  // Check if user is banned (with quick retry for read operation)
  const profile = await withRetry(
    async () => {
      const { data: profile } = await supabase
        .from('profiles')
        .select('banned')
        .eq('user_id', userId)
        .single();
      return profile;
    },
    { maxAttempts: 2 }
  );

  if (profile?.banned) {
    throw new Error('Account suspended. Contact support for assistance.');
  }

  // Upload any pending local images first
  let processedImages = data.images;
  if (data.images?.uploaded && data.images.uploaded.length > 0) {
    try {
      const uploadedImages = await uploadPendingImages(data.images.uploaded);
      processedImages = {
        ...data.images,
        uploaded: uploadedImages
      };
    } catch (error: unknown) {
      handleError(error, {
        action: 'Upload company images',
        metadata: { companyType },
      });
      throw new Error('Failed to upload images. Please check your connection and try again.');
    }
  }

  // Create submission with retry logic
  const retryId = crypto.randomUUID();
  
  const result = await withRetry(
    async () => {
      // Create the main submission record
      const { data: submissionData, error: submissionError } = await supabase
        .from('content_submissions')
        .insert({
          user_id: userId,
          submission_type: companyType,
          content: {
            action: 'create'
          },
          status: 'pending' as const
        })
        .select('id')
        .single();

      if (submissionError) throw submissionError;

      // Create the submission item with actual company data
      const { error: itemError } = await supabase
        .from('submission_items')
        .insert({
          submission_id: submissionData.id,
          item_type: companyType,
          item_data: {
            name: data.name,
            slug: data.slug,
            description: data.description,
            person_type: data.person_type,
            website_url: data.website_url,
            founded_year: data.founded_year,
            headquarters_location: data.headquarters_location,
            company_type: companyType,
            images: processedImages as unknown as Json
          },
          status: 'pending' as const,
          order_index: 0
        });

      if (itemError) throw itemError;

      return { submitted: true, submissionId: submissionData.id };
    },
    {
      maxAttempts: 3,
      onRetry: (attempt, error, delay) => {
        logger.warn('Retrying company submission', { attempt, delay, companyType });
        
        // Emit event for UI indicator
        window.dispatchEvent(new CustomEvent('submission-retry', {
          detail: { id: retryId, attempt, maxAttempts: 3, delay, type: companyType }
        }));
      },
      shouldRetry: (error) => {
        // Don't retry validation/business logic errors
        if (error instanceof Error) {
          const message = error.message.toLowerCase();
          if (message.includes('required')) return false;
          if (message.includes('banned')) return false;
          if (message.includes('slug')) return false;
          if (message.includes('permission')) return false;
        }
        
        return isRetryableError(error);
      }
    }
  ).then((data) => {
    // Emit success event
    window.dispatchEvent(new CustomEvent('submission-retry-success', {
      detail: { id: retryId }
    }));
    return data;
  }).catch((error) => {
    const errorId = handleError(error, {
      action: `${companyType} submission`,
      metadata: { retriesExhausted: true },
    });
    
    // Emit failure event
    window.dispatchEvent(new CustomEvent('submission-retry-failed', {
      detail: { id: retryId, errorId }
    }));
    
    throw error;
  });

  return result;
}

export async function submitCompanyUpdate(
  companyId: string,
  data: CompanyFormData,
  userId: string
) {
  // Check if user is banned (with quick retry for read operation)
  const profile = await withRetry(
    async () => {
      const { data: profile } = await supabase
        .from('profiles')
        .select('banned')
        .eq('user_id', userId)
        .single();
      return profile;
    },
    { maxAttempts: 2 }
  );

  if (profile?.banned) {
    throw new Error('Account suspended. Contact support for assistance.');
  }

  // Fetch existing company data (all fields for original_data)
  const { data: existingCompany, error: fetchError } = await supabase
    .from('companies')
    .select('id, name, slug, description, company_type, person_type, logo_url, card_image_url, banner_image_url, banner_image_id, card_image_id, headquarters_location, website_url, founded_year, founded_date, founded_date_precision')
    .eq('id', companyId)
    .single();

  if (fetchError) throw fetchError;
  if (!existingCompany) throw new Error('Company not found');

  // Upload any pending local images first
  let processedImages = data.images;
  if (data.images?.uploaded && data.images.uploaded.length > 0) {
    try {
      const uploadedImages = await uploadPendingImages(data.images.uploaded);
      processedImages = {
        ...data.images,
        uploaded: uploadedImages
      };
    } catch (error: unknown) {
      handleError(error, {
        action: 'Upload company images for update',
        metadata: { companyType: existingCompany.company_type, companyId },
      });
      throw new Error('Failed to upload images. Please check your connection and try again.');
    }
  }

  // Create submission with retry logic
  const retryId = crypto.randomUUID();
  
  const result = await withRetry(
    async () => {
      // Create the main submission record
      const { data: submissionData, error: submissionError } = await supabase
        .from('content_submissions')
        .insert({
          user_id: userId,
          submission_type: existingCompany.company_type,
          content: {
            action: 'edit',
            company_id: companyId
          },
          status: 'pending' as const
        })
        .select('id')
        .single();

      if (submissionError) throw submissionError;

      // Create the submission item with actual company data AND original data
      const { error: itemError } = await supabase
        .from('submission_items')
        .insert({
          submission_id: submissionData.id,
          item_type: existingCompany.company_type,
          item_data: {
            company_id: companyId,
            name: data.name,
            slug: data.slug,
            description: data.description,
            person_type: data.person_type,
            website_url: data.website_url,
            founded_year: data.founded_year,
            headquarters_location: data.headquarters_location,
            images: processedImages as unknown as Json
          },
          original_data: JSON.parse(JSON.stringify(existingCompany)),
          status: 'pending' as const,
          order_index: 0
        });

      if (itemError) throw itemError;

      return { submitted: true, submissionId: submissionData.id };
    },
    {
      maxAttempts: 3,
      onRetry: (attempt, error, delay) => {
        logger.warn('Retrying company update', { attempt, delay, companyId });
        
        // Emit event for UI indicator
        window.dispatchEvent(new CustomEvent('submission-retry', {
          detail: { id: retryId, attempt, maxAttempts: 3, delay, type: `${existingCompany.company_type} update` }
        }));
      },
      shouldRetry: (error) => {
        // Don't retry validation/business logic errors
        if (error instanceof Error) {
          const message = error.message.toLowerCase();
          if (message.includes('required')) return false;
          if (message.includes('banned')) return false;
          if (message.includes('slug')) return false;
          if (message.includes('permission')) return false;
        }
        
        return isRetryableError(error);
      }
    }
  ).then((data) => {
    // Emit success event
    window.dispatchEvent(new CustomEvent('submission-retry-success', {
      detail: { id: retryId }
    }));
    return data;
  }).catch((error) => {
    const errorId = handleError(error, {
      action: `${existingCompany.company_type} update`,
      metadata: { retriesExhausted: true, companyId },
    });
    
    // Emit failure event
    window.dispatchEvent(new CustomEvent('submission-retry-failed', {
      detail: { id: retryId, errorId }
    }));
    
    throw error;
  });

  return result;
}
