-- 13-rental-type-daily-and-email-guard.sql
-- Introduce explicit 'single_day' rental_type, normalize legacy values,
-- and harden auto-email guard for individuell rentals.

-- =============================================================================
-- A. Normalize and expand rental_type checks
-- =============================================================================

alter table public.leads drop constraint if exists leads_rental_type_check;
alter table public.sales_orders drop constraint if exists sales_orders_rental_type_check;

update public.leads
   set rental_type = lower(trim(coalesce(rental_type, '')));

update public.sales_orders
   set rental_type = lower(trim(coalesce(rental_type, '')));

update public.leads
   set rental_type = 'individuell'
 where rental_type in ('individual', 'custom');

update public.sales_orders
   set rental_type = 'individuell'
 where rental_type in ('individual', 'custom');

update public.leads
   set rental_type = 'single_day'
 where rental_type in ('day', 'daily', '1 tag', '1_tag', 'single_day');

update public.sales_orders
   set rental_type = 'single_day'
 where rental_type in ('day', 'daily', '1 tag', '1_tag', 'single_day');

-- Existing one-day bookings should be single_day.
update public.leads
   set rental_type = 'single_day'
 where rental_type = 'weekend'
   and total_days = 1;

update public.sales_orders
   set rental_type = 'single_day'
 where rental_type = 'weekend'
   and total_days = 1;

-- Two-day non-Saturday starts are effectively single_day rentals, not weekend packages.
update public.leads
   set rental_type = 'single_day'
 where rental_type = 'weekend'
   and total_days = 2
   and date_from is not null
   and extract(isodow from date_from) <> 6;

update public.sales_orders
   set rental_type = 'single_day'
 where rental_type = 'weekend'
   and total_days = 2
   and date_from is not null
   and extract(isodow from date_from) <> 6;

-- Fallback for any unexpected value.
update public.leads
   set rental_type = 'weekend'
 where rental_type not in ('single_day', 'weekend', 'individuell');

update public.sales_orders
   set rental_type = 'weekend'
 where rental_type not in ('single_day', 'weekend', 'individuell');

alter table public.leads
    alter column rental_type set default 'weekend';

alter table public.sales_orders
    alter column rental_type set default 'weekend';

alter table public.leads
    add constraint leads_rental_type_check
    check (rental_type in ('single_day', 'weekend', 'individuell'));

alter table public.sales_orders
    add constraint sales_orders_rental_type_check
    check (rental_type in ('single_day', 'weekend', 'individuell'));

-- =============================================================================
-- B. Harden notify_lead_qualified() against malformed rental_type values
-- =============================================================================

create or replace function public.notify_lead_qualified()
returns trigger
language plpgsql
security definer
as $$
declare
    v_rental_type text := coalesce(lower(trim(NEW.rental_type)), 'weekend');
begin
    -- Never auto-email individuell orders (including legacy synonyms).
    if v_rental_type in ('individuell', 'individual', 'custom') then
        return NEW;
    end if;

    perform pg_notify('lead_qualified', json_build_object(
        'sales_order_id', NEW.id,
        'customer_id', NEW.customer_id,
        'lead_id', NEW.lead_id,
        'order_number', NEW.order_number,
        'total_eur', NEW.total_eur,
        'deposit_eur', NEW.deposit_eur,
        'date_from', NEW.date_from,
        'date_to', NEW.date_to,
        'vehicle_label', NEW.vehicle_label,
        'rental_type', v_rental_type,
        'email_sent', NEW.email_sent
    )::text);

    return NEW;
end;
$$;

-- =============================================================================
-- C. Update create_lead() classification logic to include daily
-- =============================================================================

create or replace function public.create_lead(
    p_name text,
    p_email text,
    p_phone text default '',
    p_vehicle_id uuid default null,
    p_vehicle_label text default '',
    p_date_from date default null,
    p_date_to date default null,
    p_message text default '',
    p_source text default 'website',
    p_ip_address text default '',
    p_ip_country text default ''
)
returns uuid
language plpgsql
security definer
as $$
declare
    v_lead_id uuid;
    v_vehicle record;
    v_total_days integer := 0;
    v_weekend_days integer := 0;
    v_weekdays integer := 0;
    v_daily_subtotal integer := 0;
    v_weekend_subtotal integer := 0;
    v_subtotal_eur integer := 0;
    v_vat_eur integer := 0;
    v_total_eur integer := 0;
    v_deposit_eur integer := 0;
    v_rental_type text := 'weekend';
    v_cur date;
    v_dow integer;
begin
    if p_vehicle_id is not null and p_date_from is not null and p_date_to is not null and p_date_to > p_date_from then
        select daily_price_eur, weekend_price_eur, kaution_eur
          into v_vehicle
          from public.vehicles
         where id = p_vehicle_id;

        if found then
            v_total_days := (p_date_to - p_date_from);

            -- Classification:
            -- 1 day => single_day
            -- 2 days starting Saturday => weekend package
            -- 2 days otherwise => single_day
            -- > 2 days => individuell (manual processing)
            if v_total_days > 2 then
                v_rental_type := 'individuell';
            elsif v_total_days = 1 then
                v_rental_type := 'single_day';
            elsif v_total_days = 2 and extract(isodow from p_date_from) = 6 then
                v_rental_type := 'weekend';
            elsif v_total_days = 2 then
                v_rental_type := 'single_day';
            else
                v_rental_type := 'weekend';
            end if;

            if v_rental_type = 'individuell' then
                v_daily_subtotal := 0;
                v_weekend_subtotal := 0;
                v_subtotal_eur := 0;
                v_vat_eur := 0;
                v_total_eur := 0;
                v_deposit_eur := 0;
            else
                v_cur := p_date_from;
                while v_cur < p_date_to loop
                    v_dow := extract(isodow from v_cur);
                    if v_dow in (6, 7) then
                        v_weekend_days := v_weekend_days + 1;
                    end if;
                    v_cur := v_cur + 1;
                end loop;

                v_weekdays := v_total_days - v_weekend_days;
                v_daily_subtotal := v_weekdays * v_vehicle.daily_price_eur;
                v_weekend_subtotal := v_weekend_days * (case when v_vehicle.weekend_price_eur > 0 then v_vehicle.weekend_price_eur else v_vehicle.daily_price_eur end);
                v_subtotal_eur := v_daily_subtotal + v_weekend_subtotal;
                v_vat_eur := round(v_subtotal_eur * 0.20);
                v_total_eur := v_subtotal_eur + v_vat_eur;
                v_deposit_eur := coalesce(nullif(v_vehicle.kaution_eur, 0), 5000);
            end if;
        end if;
    end if;

    insert into public.leads (
        name, email, phone, vehicle_id, vehicle_label, date_from, date_to,
        message, source,
        daily_subtotal, weekend_subtotal, subtotal_eur, vat_eur, total_eur, deposit_eur,
        total_days, weekday_count, weekend_day_count, ip_address, ip_country,
        rental_type
    ) values (
        p_name, p_email, p_phone, p_vehicle_id, p_vehicle_label, p_date_from, p_date_to,
        p_message, p_source,
        v_daily_subtotal, v_weekend_subtotal, v_subtotal_eur, v_vat_eur, v_total_eur, v_deposit_eur,
        v_total_days, v_weekdays, v_weekend_days, p_ip_address, p_ip_country,
        v_rental_type
    )
    returning id into v_lead_id;

    return v_lead_id;
end;
$$;

grant execute on function public.create_lead(
    text, text, text, uuid, text, date, date, text, text, text, text
) to anon, authenticated, service_role;

notify pgrst, 'reload schema';
