import React, { createContext, useContext, useEffect, useState, useCallback } from 'react';
import { supabase } from '@/lib/supabase';
import { toast } from '@/components/ui/use-toast';
import type {
  Load,
  Driver,
  Truck,
  Trailer,
  Broker,
  Invoice,
  LoadStatus,
} from '@/lib/fleetData';

interface FleetDataCtx {
  loads: Load[];
  drivers: Driver[];
  trucks: Truck[];
  trailers: Trailer[];
  brokers: Broker[];
  invoices: Invoice[];
  loading: boolean;
  refresh: () => Promise<void>;
  addLoad: (l: Omit<Load, 'id'>) => Promise<void>;
  updateLoadStatus: (id: string, status: LoadStatus) => Promise<void>;
  updateLoad: (id: string, patch: Partial<Load>) => Promise<void>;
  deleteLoad: (id: string) => Promise<void>;
  addInvoice: (i: Omit<Invoice, 'id'>) => Promise<void>;
  updateBroker: (id: string, patch: Partial<Broker>) => Promise<void>;
}

const Ctx = createContext<FleetDataCtx | undefined>(undefined);

export const FleetDataProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [loads, setLoads] = useState<Load[]>([]);
  const [drivers, setDrivers] = useState<Driver[]>([]);
  const [trucks, setTrucks] = useState<Truck[]>([]);
  const [trailers, setTrailers] = useState<Trailer[]>([]);
  const [brokers, setBrokers] = useState<Broker[]>([]);
  const [invoices, setInvoices] = useState<Invoice[]>([]);
  const [loading, setLoading] = useState(true);

  const refresh = useCallback(async () => {
    setLoading(true);
    const [l, d, t, tr, b, i] = await Promise.all([
      supabase.from('loads').select('*').order('created_at', { ascending: false }),
      supabase.from('drivers').select('*').order('name'),
      supabase.from('trucks').select('*').order('unit'),
      supabase.from('trailers').select('*').order('trailerNumber'),
      supabase.from('brokers').select('*').order('revenueYTD', { ascending: false }),
      supabase.from('invoices').select('*').order('created_at', { ascending: false }),
    ]);
    if (l.data) setLoads(l.data as Load[]);
    if (d.data) setDrivers(d.data as Driver[]);
    if (t.data) setTrucks(t.data as Truck[]);
    if (tr.data) setTrailers(tr.data as Trailer[]);
    if (b.data) setBrokers(b.data as Broker[]);
    if (i.data) setInvoices(i.data as Invoice[]);
    setLoading(false);
  }, []);

  useEffect(() => {
    refresh();
  }, [refresh]);

  const addLoad = async (l: Omit<Load, 'id'>) => {
    const { data, error } = await supabase.from('loads').insert(l).select().single();
    if (error) {
      toast({ title: 'Could not save load', description: error.message });
      return;
    }
    setLoads((p) => [data as Load, ...p]);
    toast({ title: 'Load created', description: `${(data as Load).loadNumber} saved to the database.` });
  };

  const updateLoadStatus = async (id: string, status: LoadStatus) => {
    setLoads((p) => p.map((x) => (x.id === id ? { ...x, status } : x)));
    const { error } = await supabase.from('loads').update({ status }).eq('id', id);
    if (error) {
      toast({ title: 'Update failed', description: error.message });
      refresh();
    }
  };

  const updateLoad = async (id: string, patch: Partial<Load>) => {
    setLoads((p) => p.map((x) => (x.id === id ? { ...x, ...patch } : x)));
    const { error } = await supabase.from('loads').update(patch).eq('id', id);
    if (error) {
      toast({ title: 'Update failed', description: error.message });
      refresh();
    }
  };

  const deleteLoad = async (id: string) => {
    const prev = loads;
    setLoads((p) => p.filter((x) => x.id !== id));
    const { error } = await supabase.from('loads').delete().eq('id', id);
    if (error) {
      toast({ title: 'Delete failed', description: error.message });
      setLoads(prev);
    } else {
      toast({ title: 'Load deleted' });
    }
  };

  const addInvoice = async (i: Omit<Invoice, 'id'>) => {
    const { data, error } = await supabase.from('invoices').insert(i).select().single();
    if (error) {
      toast({ title: 'Could not create invoice', description: error.message });
      return;
    }
    setInvoices((p) => [data as Invoice, ...p]);
    toast({ title: 'Invoice created', description: `${(data as Invoice).invoiceNumber} saved.` });
  };

  const updateBroker = async (id: string, patch: Partial<Broker>) => {
    setBrokers((p) => p.map((x) => (x.id === id ? { ...x, ...patch } : x)));
    const { error } = await supabase.from('brokers').update(patch).eq('id', id);
    if (error) {
      toast({ title: 'Update failed', description: error.message });
      refresh();
    }
  };

  return (
    <Ctx.Provider
      value={{
        loads,
        drivers,
        trucks,
        trailers,
        brokers,
        invoices,
        loading,
        refresh,
        addLoad,
        updateLoadStatus,
        updateLoad,
        deleteLoad,
        addInvoice,
        updateBroker,
      }}
    >
      {children}
    </Ctx.Provider>
  );
};

export const useFleetData = () => {
  const c = useContext(Ctx);
  if (!c) throw new Error('useFleetData must be used within FleetDataProvider');
  return c;
};
