-- Vendor email mapping for inbound bill parsing
CREATE TABLE public.vendor_email_mappings (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  email TEXT NOT NULL,
  association_id UUID NOT NULL REFERENCES public.associations(id) ON DELETE CASCADE,
  vendor_id UUID REFERENCES public.vendors(id) ON DELETE SET NULL,
  vendor_name TEXT,
  notes TEXT,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  created_by UUID,
  UNIQUE (email, association_id)
);

CREATE INDEX idx_vendor_email_mappings_email ON public.vendor_email_mappings (lower(email));
CREATE INDEX idx_vendor_email_mappings_association ON public.vendor_email_mappings (association_id);

ALTER TABLE public.vendor_email_mappings ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Staff can view vendor email mappings"
ON public.vendor_email_mappings 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 manage vendor email mappings"
ON public.vendor_email_mappings FOR ALL 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 TRIGGER update_vendor_email_mappings_updated_at
BEFORE UPDATE ON public.vendor_email_mappings
FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();

-- Quarantine table for inbound bill emails (unknown sender or parse failure)
CREATE TABLE public.inbound_bill_emails (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  from_email TEXT,
  from_name TEXT,
  to_email TEXT,
  subject TEXT,
  body_text TEXT,
  attachment_url TEXT,
  attachment_filename TEXT,
  attachment_storage_path TEXT,
  parsed_data JSONB,
  status TEXT NOT NULL DEFAULT 'unassigned', -- unassigned | processed | rejected | error
  error_message TEXT,
  association_id UUID REFERENCES public.associations(id) ON DELETE SET NULL,
  bill_id UUID REFERENCES public.bills(id) ON DELETE SET NULL,
  raw_payload JSONB,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  processed_at TIMESTAMP WITH TIME ZONE,
  processed_by UUID
);

CREATE INDEX idx_inbound_bill_emails_status ON public.inbound_bill_emails (status, created_at DESC);
CREATE INDEX idx_inbound_bill_emails_assoc ON public.inbound_bill_emails (association_id);

ALTER TABLE public.inbound_bill_emails ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Staff can view inbound bill emails"
ON public.inbound_bill_emails 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 manage inbound bill emails"
ON public.inbound_bill_emails FOR ALL 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 TRIGGER update_inbound_bill_emails_updated_at
BEFORE UPDATE ON public.inbound_bill_emails
FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();

-- Storage bucket for inbound email attachments (private)
INSERT INTO storage.buckets (id, name, public)
VALUES ('inbound-bill-attachments', 'inbound-bill-attachments', false)
ON CONFLICT (id) DO NOTHING;

CREATE POLICY "Staff can read inbound bill attachments"
ON storage.objects FOR SELECT TO authenticated
USING (
  bucket_id = 'inbound-bill-attachments'
  AND (public.has_role(auth.uid(), 'admin'::public.app_role) OR public.has_role(auth.uid(), 'manager'::public.app_role))
);

CREATE POLICY "Staff can upload inbound bill attachments"
ON storage.objects FOR INSERT TO authenticated
WITH CHECK (
  bucket_id = 'inbound-bill-attachments'
  AND (public.has_role(auth.uid(), 'admin'::public.app_role) OR public.has_role(auth.uid(), 'manager'::public.app_role))
);