-- =============================================================================
-- MC Cars - Booking flow enhancements: weekend pricing, daily KM limits,
-- lead attachments, customer attachments, email-based customer upsert.
-- Idempotent.
-- =============================================================================

-- -----------------------------------------------------------------------------
-- 1. Add weekend_price_eur and max_daily_km to vehicles
-- -----------------------------------------------------------------------------
alter table public.vehicles add column if not exists weekend_price_eur integer not null default 0;
alter table public.vehicles add column if not exists max_daily_km     integer not null default 0;

-- Backfill existing vehicles with sensible defaults (weekend = daily * 1.2)
update public.vehicles
   set weekend_price_eur = ceil(daily_price_eur * 1.2),
       max_daily_km      = 150
 where weekend_price_eur = 0;

-- Ferrari gets specific pricing
update public.vehicles
   set weekend_price_eur = 1100,
       max_daily_km      = 200
 where brand = 'Ferrari' and model = '296 GTB';

-- -----------------------------------------------------------------------------
-- 2. Lead attachments: documents uploaded during booking flow
-- -----------------------------------------------------------------------------
create table if not exists public.lead_attachments (
    id          uuid primary key default gen_random_uuid(),
    lead_id     uuid not null references public.leads(id) on delete cascade,
    bucket      text not null default 'customer-documents',
    file_path   text not null,
    file_name   text not null default '',
    mime_type   text not null default 'application/octet-stream',
    kind        text not null default 'other'
                check (kind in ('id_document', 'income_proof', 'other')),
    created_at  timestamptz not null default now()
);

create index if not exists lead_attachments_lead_idx on public.lead_attachments (lead_id);

alter table public.lead_attachments enable row level security;

drop policy if exists "lead_attach_anon_insert" on public.lead_attachments;
drop policy if exists "lead_attach_admin_all"   on public.lead_attachments;

-- Anon can insert (they upload during booking)
create policy "lead_attach_anon_insert"
    on public.lead_attachments for insert to anon
    with check (true);

-- Authenticated admins can do everything
create policy "lead_attach_admin_all"
    on public.lead_attachments for all to authenticated
    using (true) with check (true);

grant insert on public.lead_attachments to anon;
grant all on public.lead_attachments to authenticated;
grant all on public.lead_attachments to service_role;

-- -----------------------------------------------------------------------------
-- 3. Customer attachments: transferred from leads on qualification
-- -----------------------------------------------------------------------------
create table if not exists public.customer_attachments (
    id           uuid primary key default gen_random_uuid(),
    customer_id  uuid not null references public.customers(id) on delete cascade,
    lead_id      uuid references public.leads(id) on delete set null,
    bucket       text not null default 'customer-documents',
    file_path    text not null,
    file_name    text not null default '',
    mime_type    text not null default 'application/octet-stream',
    kind         text not null default 'other'
                 check (kind in ('id_document', 'income_proof', 'other')),
    created_at   timestamptz not null default now()
);

create index if not exists customer_attachments_cust_idx on public.customer_attachments (customer_id);

alter table public.customer_attachments enable row level security;

drop policy if exists "cust_attach_admin_all" on public.customer_attachments;

create policy "cust_attach_admin_all"
    on public.customer_attachments for all to authenticated
    using (true) with check (true);

grant all on public.customer_attachments to authenticated;
grant all on public.customer_attachments to service_role;

-- -----------------------------------------------------------------------------
-- 4. Allow multiple leads per customer: drop UNIQUE on lead_id, add email index
-- -----------------------------------------------------------------------------
-- Drop the unique index on customers.lead_id so multiple leads can map to one customer
drop index if exists customers_lead_unique;

-- Create unique index on email for upsert
create unique index if not exists customers_email_unique on public.customers (lower(email));

-- -----------------------------------------------------------------------------
-- 5. Replace qualify_lead() with email-based upsert + attachment transfer
-- -----------------------------------------------------------------------------
create or replace function public.qualify_lead(p_lead_id uuid, p_notes text default '')
returns public.customers
language plpgsql
security invoker
as $$
declare
    v_lead public.leads;
    v_customer public.customers;
    v_user uuid := auth.uid();
begin
    -- Lock the lead row
    select * into v_lead from public.leads where id = p_lead_id for update;
    if not found then
        raise exception 'lead % not found', p_lead_id;
    end if;

    -- If already qualified, just return the associated customer
    if v_lead.status = 'qualified' then
        select * into v_customer from public.customers where lead_id = v_lead.id limit 1;
        if not found then
            select * into v_customer from public.customers where lower(email) = lower(v_lead.email) limit 1;
        end if;
        return v_customer;
    end if;

    -- Mark lead as qualified
    update public.leads
       set status       = 'qualified',
           is_active    = false,
           qualified_at = now(),
           qualified_by = v_user,
           admin_notes  = coalesce(nullif(p_notes, ''), admin_notes)
     where id = v_lead.id;

    -- Upsert customer by email
    insert into public.customers (lead_id, name, email, phone, notes, created_by)
    values (v_lead.id, v_lead.name, v_lead.email, v_lead.phone, coalesce(p_notes,''), v_user)
    on conflict ((lower(email))) do update
       set name       = excluded.name,
           phone      = excluded.phone,
           notes      = case when excluded.notes <> '' then excluded.notes else public.customers.notes end,
           updated_at = now()
    returning * into v_customer;

    -- Transfer lead attachments to customer
    insert into public.customer_attachments (customer_id, lead_id, bucket, file_path, file_name, mime_type, kind, created_at)
    select v_customer.id, la.lead_id, la.bucket, la.file_path, la.file_name, la.mime_type, la.kind, la.created_at
      from public.lead_attachments la
     where la.lead_id = v_lead.id
       and not exists (
           select 1 from public.customer_attachments ca
            where ca.customer_id = v_customer.id
              and ca.file_path   = la.file_path
       );

    return v_customer;
end;
$$;

revoke all on function public.qualify_lead(uuid, text) from public;
grant execute on function public.qualify_lead(uuid, text) to authenticated;
