-- Auto-create public delivery links for rows imported into public.order_groups.
-- Run this in Supabase SQL Editor after the order_groups delivery columns exist.

create extension if not exists pgcrypto with schema extensions;

create or replace function public.next_order_group_sms_check_at(
  start_from timestamptz default now(),
  delay interval default interval '0 minutes'
)
returns timestamptz
language plpgsql
stable
as $$
declare
  v_timezone text := 'Europe/Simferopol';
  v_local_time timestamp;
  v_local_date date;
  v_work_start timestamp;
  v_work_end timestamp;
  v_candidate timestamp;
begin
  v_local_time := (start_from at time zone v_timezone) + delay;
  v_local_date := v_local_time::date;
  v_work_start := v_local_date + time '09:00';
  v_work_end := v_local_date + time '20:00';

  if v_local_time < v_work_start then
    v_candidate := v_work_start;
  elsif v_local_time >= v_work_end then
    v_candidate := (v_local_date + 1) + time '09:00';
  else
    v_candidate := v_local_time;
  end if;

  return v_candidate at time zone v_timezone;
end;
$$;

create or replace function public.build_order_group_default_available_slots(
  start_from timestamptz default now()
)
returns text[]
language sql
stable
as $$
  with candidate_days as (
    select ((start_from at time zone 'Europe/Simferopol')::date + offset_days) as delivery_day
    from generate_series(1, 2) as offset_days
  ),
  slots as (
    select format('%s, %s', delivery_day, half_day) as slot_name
    from candidate_days
    cross join (
      values ('Первая половина дня'), ('Вторая половина дня')
    ) as halves(half_day)
  )
  select coalesce(array_agg(slot_name order by slot_name), array[]::text[])
  from slots;
$$;

create or replace function public.ensure_order_group_delivery_link()
returns trigger
language plpgsql
security definer
set search_path = public, extensions
as $$
declare
  v_customer_name text;
  v_customer_phone text;
  v_order_number text;
  v_token text;
  v_token_hash text;
  v_delivery_link text;
  v_invitation_id uuid;
  v_base_url text := 'https://dost.supersamsev.ru';
begin
  if pg_trigger_depth() > 1 then
    return new;
  end if;

  if coalesce(new.status, '') <> 'ready_for_notification' then
    return new;
  end if;

  if coalesce(new.delivery_status, 'pending_confirmation') <> 'pending_confirmation' then
    return new;
  end if;

  if coalesce(new.notification_status, 'not_started') not in ('not_started', 'send_failed') then
    return new;
  end if;

  if new.delivery_link is not null or new.delivery_invitation_id is not null then
    return new;
  end if;

  v_customer_name := nullif(
    coalesce(new.customer_name, new.customer ->> 'name'),
    ''
  );
  v_customer_phone := nullif(
    coalesce(
      new.customer_phone_normalized,
      new.customer_phone,
      new.customer ->> 'phone_normalized',
      new.customer ->> 'phone',
      split_part(new.group_key, '|', 1)
    ),
    ''
  );
  v_order_number := coalesce(new.group_key::text, new.order_numbers[1]::text);

  if v_customer_phone is null then
    update public.order_groups
    set
      notification_status = 'manual_required',
      last_sms_error = 'Не найден телефон клиента для формирования SMS-ссылки',
      next_notification_check_at = null,
      updated_at = timezone('utc', now())
    where id = new.id;

    return new;
  end if;

  v_token := replace(gen_random_uuid()::text, '-', '') || replace(gen_random_uuid()::text, '-', '');
  v_token_hash := encode(digest(v_token, 'sha256'), 'hex');
  v_delivery_link := v_base_url || '/delivery/' || v_token;

  insert into public.delivery_invitations (
    order_id,
    order_group_id,
    token_hash,
    state,
    order_number,
    customer_name,
    customer_phone,
    available_slots,
    expires_at,
    sent_at
  )
  values (
    null,
    new.id,
    v_token_hash,
    'awaiting_choice',
    v_order_number,
    v_customer_name,
    v_customer_phone,
    public.build_order_group_default_available_slots(),
    timezone('utc', now()) + interval '7 days',
    null
  )
  returning id into v_invitation_id;

  update public.order_groups
  set
    delivery_invitation_id = v_invitation_id,
    delivery_link = v_delivery_link,
    notification_status = 'link_ready',
    last_sms_error = null,
    next_notification_check_at = public.next_order_group_sms_check_at(),
    updated_at = timezone('utc', now())
  where id = new.id;

  return new;
end;
$$;

drop trigger if exists order_groups_ensure_delivery_link on public.order_groups;
create trigger order_groups_ensure_delivery_link
after insert or update of status, delivery_status, notification_status, delivery_link, delivery_invitation_id
on public.order_groups
for each row
execute function public.ensure_order_group_delivery_link();

-- Backfill links for already imported groups that are still waiting for SMS.
update public.order_groups
set
  notification_status = notification_status,
  updated_at = timezone('utc', now())
where status = 'ready_for_notification'
  and delivery_status = 'pending_confirmation'
  and notification_status in ('not_started', 'send_failed')
  and delivery_link is null
  and delivery_invitation_id is null;
