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 SalesData {
  id: string;
  event_id: string;
  ticket_type_id: string;
  price: number;
  refund_status: string | null;
  checked_in: boolean;
  purchaser_email: string;
  purchaser_name: string | null;
  created_at: string;
  uuid: string;
  ticket_types: {
    name: string;
    price: number;
  };
}

export interface SalesMetrics {
  totalRevenue: number;
  netRevenue: number;
  ticketsSold: number;
  averageTicketPrice: number;
  conversionRate: number;
  refundRate: number;
}

export interface SalesFilter {
  ticketTypeId?: string;
  status?: string;
  searchTerm?: string;
  dateFrom?: string;
  dateTo?: string;
  checkedIn?: boolean;
}

export interface TimeSeries {
  date: string;
  revenue: number;
  tickets: number;
}

export interface TicketTypeBreakdown {
  ticketTypeId: string;
  ticketTypeName: string;
  sold: number;
  revenue: number;
  refunded: number;
  percentage: number;
}

export async function loadSalesData(eventId: string, filters?: SalesFilter): Promise<SalesData[]> {
  try {
    let query = supabase
      .from('tickets')
      .select(`
        id,
        event_id,
        ticket_type_id,
        price,
        refund_status,
        checked_in,
        purchaser_email,
        purchaser_name,
        created_at,
        uuid,
        ticket_types (
          name,
          price
        )
      `)
      .eq('event_id', eventId)
      .order('created_at', { ascending: false });

    // Apply filters
    if (filters?.ticketTypeId) {
      query = query.eq('ticket_type_id', filters.ticketTypeId);
    }

    if (filters?.status) {
      if (filters.status === 'confirmed') {
        query = query.or('refund_status.is.null,refund_status.eq.null');
      } else if (filters.status === 'refunded') {
        query = query.eq('refund_status', 'completed');
      } else if (filters.status === 'pending') {
        query = query.eq('refund_status', 'pending');
      } else if (filters.status === 'cancelled') {
        query = query.eq('refund_status', 'failed');
      }
    }

    if (filters?.checkedIn !== undefined) {
      query = query.eq('checked_in', filters.checkedIn);
    }

    if (filters?.searchTerm) {
      query = query.or(`purchaser_email.ilike.%${filters.searchTerm}%,purchaser_name.ilike.%${filters.searchTerm}%`);
    }

    if (filters?.dateFrom) {
      query = query.gte('created_at', filters.dateFrom);
    }

    if (filters?.dateTo) {
      query = query.lte('created_at', filters.dateTo);
    }

    const { data: sales, error } = await query;

    if (error) {
      console.error('Error loading sales data:', error);
      return [];
    }

    return sales || [];
  } catch (error) {
    console.error('Error in loadSalesData:', error);
    return [];
  }
}

export function calculateSalesMetrics(salesData: SalesData[]): SalesMetrics {
  const confirmedSales = salesData.filter(sale => !sale.refund_status || sale.refund_status === null);
  const refundedSales = salesData.filter(sale => sale.refund_status === 'completed');

  const totalRevenue = confirmedSales.reduce((sum, sale) => sum + sale.price, 0);
  const netRevenue = totalRevenue * 0.97; // Assuming 3% platform fee
  const ticketsSold = confirmedSales.length;
  const averageTicketPrice = ticketsSold > 0 ? totalRevenue / ticketsSold : 0;
  const refundRate = salesData.length > 0 ? refundedSales.length / salesData.length : 0;

  return {
    totalRevenue,
    netRevenue,
    ticketsSold,
    averageTicketPrice,
    conversionRate: 0, // Would need pageview data to calculate
    refundRate
  };
}

export function generateTimeSeries(salesData: SalesData[], groupBy: 'day' | 'week' | 'month' = 'day'): TimeSeries[] {
  const groupedData = new Map<string, { revenue: number; tickets: number }>();

  salesData.forEach(sale => {
    if (sale.refund_status && sale.refund_status !== null) return;

    const date = new Date(sale.created_at);
    let key: string;

    switch (groupBy) {
      case 'day':
        key = date.toISOString().split('T')[0];
        break;
      case 'week': {
        const weekStart = new Date(date);
        weekStart.setDate(date.getDate() - date.getDay());
        key = weekStart.toISOString().split('T')[0];
        break;
      }
      case 'month':
        key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
        break;
      default:
        key = date.toISOString().split('T')[0];
    }

    const existing = groupedData.get(key) || { revenue: 0, tickets: 0 };
    existing.revenue += sale.price;
    existing.tickets += 1;
    groupedData.set(key, existing);
  });

  return Array.from(groupedData.entries())
    .map(([date, data]) => ({
      date,
      revenue: data.revenue,
      tickets: data.tickets
    }))
    .sort((a, b) => a.date.localeCompare(b.date));
}

export function generateTicketTypeBreakdown(salesData: SalesData[]): TicketTypeBreakdown[] {
  const typeMap = new Map<string, {
    name: string;
    sold: number;
    revenue: number;
    refunded: number;
  }>();

  salesData.forEach(sale => {
    const key = sale.ticket_type_id;
    const existing = typeMap.get(key) || {
      name: sale.ticket_types.name,
      sold: 0,
      revenue: 0,
      refunded: 0
    };

    if (!sale.refund_status || sale.refund_status === null) {
      existing.sold += 1;
      existing.revenue += sale.price;
    } else if (sale.refund_status === 'completed') {
      existing.refunded += 1;
    }

    typeMap.set(key, existing);
  });

  const totalRevenue = Array.from(typeMap.values()).reduce((sum, type) => sum + type.revenue, 0);

  return Array.from(typeMap.entries())
    .map(([ticketTypeId, data]) => ({
      ticketTypeId,
      ticketTypeName: data.name,
      sold: data.sold,
      revenue: data.revenue,
      refunded: data.refunded,
      percentage: totalRevenue > 0 ? (data.revenue / totalRevenue) * 100 : 0
    }))
    .sort((a, b) => b.revenue - a.revenue);
}

export async function exportSalesData(eventId: string, format: 'csv' | 'json' = 'csv'): Promise<string> {
  try {
    const salesData = await loadSalesData(eventId);
    
    if (format === 'json') {
      return JSON.stringify(salesData, null, 2);
    }

    // CSV format
    const headers = [
      'Order ID',
      'Purchaser Name',
      'Purchaser Email',
      'Ticket Type',
      'Price Paid',
      'Status',
      'Checked In',
      'Purchase Date',
      'Ticket UUID'
    ];

    const rows = salesData.map(sale => [
      sale.id,
      sale.purchaser_name || '',
      sale.purchaser_email,
      sale.ticket_types.name,
      formatCurrency(sale.price),
      (!sale.refund_status || sale.refund_status === null) ? 'confirmed' : 
       sale.refund_status === 'completed' ? 'refunded' : 
       sale.refund_status === 'pending' ? 'pending' : 'failed',
      sale.checked_in ? 'Yes' : 'No',
      new Date(sale.created_at).toLocaleDateString(),
      sale.uuid
    ]);

    return [
      headers.join(','),
      ...rows.map(row => row.map(cell => `"${cell}"`).join(','))
    ].join('\n');
  } catch (error) {
    console.error('Error exporting sales data:', error);
    return '';
  }
}

export function formatCurrency(cents: number): string {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD'
  }).format(cents / 100);
}

export function formatPercentage(value: number): string {
  return new Intl.NumberFormat('en-US', {
    style: 'percent',
    minimumFractionDigits: 1,
    maximumFractionDigits: 1
  }).format(value / 100);
}

export function generateSalesReport(salesData: SalesData[]): {
  summary: SalesMetrics;
  timeSeries: TimeSeries[];
  ticketTypeBreakdown: TicketTypeBreakdown[];
} {
  return {
    summary: calculateSalesMetrics(salesData),
    timeSeries: generateTimeSeries(salesData),
    ticketTypeBreakdown: generateTicketTypeBreakdown(salesData)
  };
}