-- Flag rentals as owner-occupied (owner using their own lot)
ALTER TABLE public.rv_boat_lot_rentals
  ADD COLUMN IF NOT EXISTS is_owner BOOLEAN NOT NULL DEFAULT false;

-- Helpers for rv_owner role (owner_ids and association_ids the user has access to)
CREATE OR REPLACE FUNCTION public.get_rv_owner_owner_ids(_user_id uuid DEFAULT auth.uid())
RETURNS SETOF uuid
LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public
AS $$
  SELECT DISTINCT r.owner_id
  FROM public.rv_boat_lot_rentals r
  WHERE r.user_id = _user_id
    AND r.is_owner = true
    AND r.owner_id IS NOT NULL
    AND r.status = 'active'
$$;

CREATE OR REPLACE FUNCTION public.get_rv_owner_association_ids(_user_id uuid DEFAULT auth.uid())
RETURNS SETOF uuid
LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public
AS $$
  SELECT DISTINCT r.association_id
  FROM public.rv_boat_lot_rentals r
  WHERE r.user_id = _user_id
    AND r.is_owner = true
    AND r.status = 'active'
$$;

-- RV owners can read their own rental row (covers the is_owner = true rows)
CREATE POLICY "RV owners can view their own rental"
ON public.rv_boat_lot_rentals
FOR SELECT
TO authenticated
USING (user_id = auth.uid() AND is_owner = true);

-- RV owners can read their lot
CREATE POLICY "RV owners can view their lot"
ON public.rv_boat_lots
FOR SELECT
TO authenticated
USING (
  EXISTS (
    SELECT 1 FROM public.rv_boat_lot_rentals r
    WHERE r.lot_id = rv_boat_lots.id
      AND r.user_id = auth.uid()
      AND r.is_owner = true
      AND r.status = 'active'
  )
);

-- RV owners can read their association
CREATE POLICY "RV owners can view their association"
ON public.associations
FOR SELECT
TO authenticated
USING (id IN (SELECT public.get_rv_owner_association_ids(auth.uid())));

-- RV owners can read the linked owner ledger
CREATE POLICY "RV owners can view linked owner ledger"
ON public.owner_ledger_entries
FOR SELECT
TO authenticated
USING (owner_id IN (SELECT public.get_rv_owner_owner_ids(auth.uid())));

-- RV owners can read the linked owner record
CREATE POLICY "RV owners can view linked owner"
ON public.owners
FOR SELECT
TO authenticated
USING (id IN (SELECT public.get_rv_owner_owner_ids(auth.uid())));

-- Intent to Vacate
CREATE TABLE IF NOT EXISTS public.rv_intent_to_vacate (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  rental_id UUID NOT NULL REFERENCES public.rv_boat_lot_rentals(id) ON DELETE CASCADE,
  association_id UUID NOT NULL REFERENCES public.associations(id) ON DELETE CASCADE,
  lot_id UUID REFERENCES public.rv_boat_lots(id) ON DELETE SET NULL,
  owner_id UUID REFERENCES public.owners(id) ON DELETE SET NULL,
  submitted_by_user_id UUID REFERENCES auth.users(id) ON DELETE SET NULL,
  vacate_date DATE NOT NULL,
  notes TEXT,
  status TEXT NOT NULL DEFAULT 'pending',
  acknowledged_at TIMESTAMP WITH TIME ZONE,
  acknowledged_by_user_id UUID REFERENCES auth.users(id) ON DELETE SET NULL,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS rv_itv_rental_idx ON public.rv_intent_to_vacate(rental_id);
CREATE INDEX IF NOT EXISTS rv_itv_assoc_idx ON public.rv_intent_to_vacate(association_id);
CREATE INDEX IF NOT EXISTS rv_itv_user_idx ON public.rv_intent_to_vacate(submitted_by_user_id);

ALTER TABLE public.rv_intent_to_vacate ENABLE ROW LEVEL SECURITY;

CREATE TRIGGER update_rv_intent_to_vacate_updated_at
BEFORE UPDATE ON public.rv_intent_to_vacate
FOR EACH ROW
EXECUTE FUNCTION public.update_updated_at_column();

-- RLS: RV owners manage their own intents
CREATE POLICY "RV owners can view their intents"
ON public.rv_intent_to_vacate
FOR SELECT
TO authenticated
USING (submitted_by_user_id = auth.uid());

CREATE POLICY "RV owners can submit intents for their rental"
ON public.rv_intent_to_vacate
FOR INSERT
TO authenticated
WITH CHECK (
  submitted_by_user_id = auth.uid()
  AND EXISTS (
    SELECT 1 FROM public.rv_boat_lot_rentals r
    WHERE r.id = rv_intent_to_vacate.rental_id
      AND r.user_id = auth.uid()
      AND r.is_owner = true
      AND r.status = 'active'
  )
);

CREATE POLICY "RV owners can cancel their pending intents"
ON public.rv_intent_to_vacate
FOR UPDATE
TO authenticated
USING (submitted_by_user_id = auth.uid() AND status = 'pending')
WITH CHECK (submitted_by_user_id = auth.uid());

-- Staff can manage all
CREATE POLICY "Staff can view all intents"
ON public.rv_intent_to_vacate
FOR SELECT
TO authenticated
USING (
  public.has_role(auth.uid(), 'admin'::public.app_role)
  OR public.has_role(auth.uid(), 'manager'::public.app_role)
);

CREATE POLICY "Staff can update all intents"
ON public.rv_intent_to_vacate
FOR UPDATE
TO authenticated
USING (
  public.has_role(auth.uid(), 'admin'::public.app_role)
  OR public.has_role(auth.uid(), 'manager'::public.app_role)
)
WITH CHECK (
  public.has_role(auth.uid(), 'admin'::public.app_role)
  OR public.has_role(auth.uid(), 'manager'::public.app_role)
);

CREATE POLICY "Staff can delete intents"
ON public.rv_intent_to_vacate
FOR DELETE
TO authenticated
USING (
  public.has_role(auth.uid(), 'admin'::public.app_role)
  OR public.has_role(auth.uid(), 'manager'::public.app_role)
);

-- Notify staff when an Intent to Vacate is submitted
CREATE OR REPLACE FUNCTION public.notify_staff_on_rv_intent_to_vacate()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
  staff_user record;
  v_renter text;
  v_message text;
BEGIN
  SELECT r.renter_name INTO v_renter
  FROM public.rv_boat_lot_rentals r WHERE r.id = NEW.rental_id;

  v_message := COALESCE(v_renter, 'An RV/Boat lot owner')
    || ' submitted an Intent to Vacate effective '
    || to_char(NEW.vacate_date, 'Mon DD, YYYY');

  FOR staff_user IN
    SELECT DISTINCT user_id FROM public.user_roles
    WHERE role IN ('admin'::public.app_role, 'manager'::public.app_role)
      AND user_id IS NOT NULL
  LOOP
    INSERT INTO public.in_app_notifications
      (user_id, type, title, message, related_item_id, related_item_type, link)
    VALUES (
      staff_user.user_id,
      'rv_intent_to_vacate',
      'RV/Boat Lot — Intent to Vacate',
      v_message,
      NEW.id,
      'rv_intent_to_vacate',
      '/dashboard/rv-boat-lots'
    );
  END LOOP;

  RETURN NEW;
END;
$$;

CREATE TRIGGER trg_notify_staff_on_rv_intent_to_vacate
AFTER INSERT ON public.rv_intent_to_vacate
FOR EACH ROW
EXECUTE FUNCTION public.notify_staff_on_rv_intent_to_vacate();