import { createClient } from '@supabase/supabase-js';
import type { Database } from './database.types';

const supabase = createClient<Database>(
  import.meta.env.PUBLIC_SUPABASE_URL,
  import.meta.env.PUBLIC_SUPABASE_ANON_KEY
);

export interface SeatingMap {
  id: string;
  name: string;
  layout_data: any;
  organization_id: string;
  created_at: string;
  updated_at: string;
}

export interface LayoutItem {
  id: string;
  type: 'table' | 'seat_row' | 'general_area';
  x: number;
  y: number;
  width: number;
  height: number;
  label: string;
  capacity?: number;
  rotation?: number;
  config?: any;
}

export interface SeatingMapFormData {
  name: string;
  layout_data: LayoutItem[];
}

export type LayoutType = 'theater' | 'reception' | 'concert_hall' | 'general';

export async function loadSeatingMaps(organizationId: string): Promise<SeatingMap[]> {
  try {
    const { data: seatingMaps, error } = await supabase
      .from('seating_maps')
      .select('*')
      .eq('organization_id', organizationId)
      .order('created_at', { ascending: false });

    if (error) {

      return [];
    }

    return seatingMaps || [];
  } catch (error) {

    return [];
  }
}

export async function getSeatingMap(seatingMapId: string): Promise<SeatingMap | null> {
  try {
    const { data: seatingMap, error } = await supabase
      .from('seating_maps')
      .select('*')
      .eq('id', seatingMapId)
      .single();

    if (error) {

      return null;
    }

    return seatingMap;
  } catch (error) {

    return null;
  }
}

export async function createSeatingMap(organizationId: string, seatingMapData: SeatingMapFormData): Promise<SeatingMap | null> {
  try {
    const { data: seatingMap, error } = await supabase
      .from('seating_maps')
      .insert({
        ...seatingMapData,
        organization_id: organizationId
      })
      .select()
      .single();

    if (error) {

      return null;
    }

    return seatingMap;
  } catch (error) {

    return null;
  }
}

export async function updateSeatingMap(seatingMapId: string, updates: Partial<SeatingMapFormData>): Promise<boolean> {
  try {
    const { error } = await supabase
      .from('seating_maps')
      .update(updates)
      .eq('id', seatingMapId);

    if (error) {

      return false;
    }

    return true;
  } catch (error) {

    return false;
  }
}

export async function deleteSeatingMap(seatingMapId: string): Promise<boolean> {
  try {
    // Check if any events are using this seating map
    const { data: events } = await supabase
      .from('events')
      .select('id')
      .eq('seating_map_id', seatingMapId)
      .limit(1);

    if (events && events.length > 0) {
      throw new Error('Cannot delete seating map that is in use by events');
    }

    const { error } = await supabase
      .from('seating_maps')
      .delete()
      .eq('id', seatingMapId);

    if (error) {

      return false;
    }

    return true;
  } catch (error) {

    return false;
  }
}

export async function applySeatingMapToEvent(eventId: string, seatingMapId: string): Promise<boolean> {
  try {
    const { error } = await supabase
      .from('events')
      .update({ seating_map_id: seatingMapId })
      .eq('id', eventId);

    if (error) {

      return false;
    }

    return true;
  } catch (error) {

    return false;
  }
}

export function generateInitialLayout(type: LayoutType, capacity: number = 100): LayoutItem[] {
  switch (type) {
    case 'theater':
      return generateTheaterLayout(capacity);
    case 'reception':
      return generateReceptionLayout(capacity);
    case 'concert_hall':
      return generateConcertHallLayout(capacity);
    case 'general':
      return generateGeneralLayout(capacity);
    default:
      return [];
  }
}

export function generateTheaterLayout(capacity: number): LayoutItem[] {
  const items: LayoutItem[] = [];
  const seatsPerRow = Math.ceil(Math.sqrt(capacity));
  const numRows = Math.ceil(capacity / seatsPerRow);
  const rowHeight = 40;
  const rowSpacing = 10;

  for (let row = 0; row < numRows; row++) {
    const seatsInThisRow = Math.min(seatsPerRow, capacity - (row * seatsPerRow));
    if (seatsInThisRow <= 0) break;

    items.push({
      id: `row-${row}`,
      type: 'seat_row',
      x: 50,
      y: 50 + (row * (rowHeight + rowSpacing)),
      width: seatsInThisRow * 30,
      height: rowHeight,
      label: `Row ${String.fromCharCode(65 + row)}`,
      capacity: seatsInThisRow,
      config: {
        seats: seatsInThisRow,
        numbering: 'sequential'
      }
    });
  }

  return items;
}

export function generateReceptionLayout(capacity: number): LayoutItem[] {
  const items: LayoutItem[] = [];
  const seatsPerTable = 8;
  const numTables = Math.ceil(capacity / seatsPerTable);
  const tableSize = 80;
  const spacing = 20;

  const tablesPerRow = Math.ceil(Math.sqrt(numTables));
  
  for (let i = 0; i < numTables; i++) {
    const row = Math.floor(i / tablesPerRow);
    const col = i % tablesPerRow;
    
    items.push({
      id: `table-${i + 1}`,
      type: 'table',
      x: 50 + (col * (tableSize + spacing)),
      y: 50 + (row * (tableSize + spacing)),
      width: tableSize,
      height: tableSize,
      label: `Table ${i + 1}`,
      capacity: Math.min(seatsPerTable, capacity - (i * seatsPerTable)),
      config: {
        shape: 'round',
        seating: 'around'
      }
    });
  }

  return items;
}

export function generateConcertHallLayout(capacity: number): LayoutItem[] {
  const items: LayoutItem[] = [];
  
  // Main floor
  const mainFloorCapacity = Math.floor(capacity * 0.7);
  items.push({
    id: 'main-floor',
    type: 'general_area',
    x: 50,
    y: 200,
    width: 400,
    height: 200,
    label: 'Main Floor',
    capacity: mainFloorCapacity,
    config: {
      standing: true,
      area_type: 'general_admission'
    }
  });

  // Balcony
  const balconyCapacity = capacity - mainFloorCapacity;
  if (balconyCapacity > 0) {
    items.push({
      id: 'balcony',
      type: 'general_area',
      x: 50,
      y: 50,
      width: 400,
      height: 120,
      label: 'Balcony',
      capacity: balconyCapacity,
      config: {
        standing: false,
        area_type: 'assigned_seating'
      }
    });
  }

  return items;
}

export function generateGeneralLayout(capacity: number): LayoutItem[] {
  return [{
    id: 'general-admission',
    type: 'general_area',
    x: 50,
    y: 50,
    width: 400,
    height: 300,
    label: 'General Admission',
    capacity: capacity,
    config: {
      standing: true,
      area_type: 'general_admission'
    }
  }];
}

export function calculateLayoutCapacity(layoutItems: LayoutItem[]): number {
  return layoutItems.reduce((total, item) => total + (item.capacity || 0), 0);
}

export function validateLayoutItem(item: LayoutItem): boolean {
  return !!(
    item.id &&
    item.type &&
    typeof item.x === 'number' &&
    typeof item.y === 'number' &&
    typeof item.width === 'number' &&
    typeof item.height === 'number' &&
    item.label &&
    (item.capacity === undefined || typeof item.capacity === 'number')
  );
}

export function optimizeLayout(items: LayoutItem[], containerWidth: number = 500, containerHeight: number = 400): LayoutItem[] {
  // Simple auto-arrange algorithm
  const optimized = [...items];
  const padding = 20;
  const spacing = 10;
  
  let currentX = padding;
  let currentY = padding;
  let rowHeight = 0;
  
  optimized.forEach(item => {
    // Check if item fits in current row
    if (currentX + item.width > containerWidth - padding) {
      // Move to next row
      currentX = padding;
      currentY += rowHeight + spacing;
      rowHeight = 0;
    }
    
    // Position item
    item.x = currentX;
    item.y = currentY;
    
    // Update position for next item
    currentX += item.width + spacing;
    rowHeight = Math.max(rowHeight, item.height);
  });
  
  return optimized;
}