-- ============================================================
-- BROADCAST BEAT MARKETPLACE — PHASE 1 MVP MIGRATION
-- Additive only: all tables prefixed marketplace_
-- ============================================================

-- ── TYPES ────────────────────────────────────────────────────
DROP TYPE IF EXISTS public.marketplace_profile_type CASCADE;
CREATE TYPE public.marketplace_profile_type AS ENUM ('crew', 'vendor');

DROP TYPE IF EXISTS public.marketplace_profile_status CASCADE;
CREATE TYPE public.marketplace_profile_status AS ENUM ('pending', 'active', 'rejected');

DROP TYPE IF EXISTS public.marketplace_subscription_tier CASCADE;
CREATE TYPE public.marketplace_subscription_tier AS ENUM ('free', 'pro', 'featured');

DROP TYPE IF EXISTS public.marketplace_job_type CASCADE;
CREATE TYPE public.marketplace_job_type AS ENUM ('full_time', 'part_time', 'contract', 'temp');

DROP TYPE IF EXISTS public.marketplace_listing_status CASCADE;
CREATE TYPE public.marketplace_listing_status AS ENUM ('active', 'expired', 'draft');

-- ── CORE TABLES ───────────────────────────────────────────────

-- Marketplace profiles (one per user)
CREATE TABLE IF NOT EXISTS public.marketplace_profiles (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  profile_type public.marketplace_profile_type NOT NULL,
  slug TEXT NOT NULL UNIQUE,
  status public.marketplace_profile_status NOT NULL DEFAULT 'pending',
  subscription_tier public.marketplace_subscription_tier NOT NULL DEFAULT 'free',
  stripe_customer_id TEXT,
  stripe_subscription_id TEXT,
  rejection_reason TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Crew member details
CREATE TABLE IF NOT EXISTS public.marketplace_crew_details (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  profile_id UUID NOT NULL REFERENCES public.marketplace_profiles(id) ON DELETE CASCADE,
  name TEXT NOT NULL,
  headshot_url TEXT,
  location TEXT NOT NULL,
  union_status TEXT DEFAULT 'non_union',
  day_rate INTEGER,
  bio TEXT,
  skills TEXT[] DEFAULT ARRAY[]::TEXT[],
  equipment TEXT[] DEFAULT ARRAY[]::TEXT[],
  reel_url TEXT,
  resume_url TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Vendor / company details
CREATE TABLE IF NOT EXISTS public.marketplace_vendor_details (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  profile_id UUID NOT NULL REFERENCES public.marketplace_profiles(id) ON DELETE CASCADE,
  company_name TEXT NOT NULL,
  logo_url TEXT,
  location TEXT NOT NULL,
  category TEXT NOT NULL,
  description TEXT,
  website TEXT,
  contact_email TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Job board
CREATE TABLE IF NOT EXISTS public.marketplace_jobs (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  profile_id UUID NOT NULL REFERENCES public.marketplace_profiles(id) ON DELETE CASCADE,
  title TEXT NOT NULL,
  company TEXT NOT NULL,
  location TEXT NOT NULL,
  job_type public.marketplace_job_type NOT NULL DEFAULT 'full_time',
  salary_min INTEGER,
  salary_max INTEGER,
  description TEXT NOT NULL,
  apply_url TEXT,
  apply_email TEXT,
  expires_at TIMESTAMPTZ,
  status public.marketplace_listing_status NOT NULL DEFAULT 'active',
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Gig board
CREATE TABLE IF NOT EXISTS public.marketplace_gigs (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  profile_id UUID NOT NULL REFERENCES public.marketplace_profiles(id) ON DELETE CASCADE,
  title TEXT NOT NULL,
  company TEXT NOT NULL,
  location TEXT NOT NULL,
  gig_type TEXT NOT NULL,
  rate TEXT,
  start_date DATE,
  end_date DATE,
  description TEXT NOT NULL,
  contact_method TEXT,
  expires_at TIMESTAMPTZ,
  status public.marketplace_listing_status NOT NULL DEFAULT 'active',
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ── INDEXES ───────────────────────────────────────────────────
CREATE INDEX IF NOT EXISTS idx_marketplace_profiles_user_id ON public.marketplace_profiles(user_id);
CREATE INDEX IF NOT EXISTS idx_marketplace_profiles_slug ON public.marketplace_profiles(slug);
CREATE INDEX IF NOT EXISTS idx_marketplace_profiles_status ON public.marketplace_profiles(status);
CREATE INDEX IF NOT EXISTS idx_marketplace_crew_profile_id ON public.marketplace_crew_details(profile_id);
CREATE INDEX IF NOT EXISTS idx_marketplace_vendor_profile_id ON public.marketplace_vendor_details(profile_id);
CREATE INDEX IF NOT EXISTS idx_marketplace_jobs_profile_id ON public.marketplace_jobs(profile_id);
CREATE INDEX IF NOT EXISTS idx_marketplace_jobs_status ON public.marketplace_jobs(status);
CREATE INDEX IF NOT EXISTS idx_marketplace_gigs_profile_id ON public.marketplace_gigs(profile_id);
CREATE INDEX IF NOT EXISTS idx_marketplace_gigs_status ON public.marketplace_gigs(status);

-- ── FUNCTIONS ─────────────────────────────────────────────────

-- Auto-update updated_at
CREATE OR REPLACE FUNCTION public.marketplace_set_updated_at()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$;

-- Check if user is admin (uses auth metadata to avoid recursion)
CREATE OR REPLACE FUNCTION public.marketplace_is_admin()
RETURNS BOOLEAN
LANGUAGE sql
STABLE
SECURITY DEFINER
AS $$
SELECT EXISTS (
  SELECT 1 FROM auth.users
  WHERE id = auth.uid()
  AND (
    raw_user_meta_data->>'role' = 'admin'
    OR raw_app_meta_data->>'role' = 'admin'
  )
)
$$;

-- Check if user has active pro/featured subscription
CREATE OR REPLACE FUNCTION public.marketplace_has_active_subscription()
RETURNS BOOLEAN
LANGUAGE sql
STABLE
SECURITY DEFINER
AS $$
SELECT EXISTS (
  SELECT 1 FROM public.marketplace_profiles
  WHERE user_id = auth.uid()
  AND subscription_tier IN ('pro', 'featured')
  AND status = 'active'
)
$$;

-- ── ENABLE RLS ────────────────────────────────────────────────
ALTER TABLE public.marketplace_profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.marketplace_crew_details ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.marketplace_vendor_details ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.marketplace_jobs ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.marketplace_gigs ENABLE ROW LEVEL SECURITY;

-- ── RLS POLICIES ─────────────────────────────────────────────

-- marketplace_profiles
DROP POLICY IF EXISTS "mp_public_read_active" ON public.marketplace_profiles;
CREATE POLICY "mp_public_read_active" ON public.marketplace_profiles
  FOR SELECT TO public
  USING (status = 'active');

DROP POLICY IF EXISTS "mp_owner_read_own" ON public.marketplace_profiles;
CREATE POLICY "mp_owner_read_own" ON public.marketplace_profiles
  FOR SELECT TO authenticated
  USING (user_id = auth.uid());

DROP POLICY IF EXISTS "mp_owner_insert" ON public.marketplace_profiles;
CREATE POLICY "mp_owner_insert" ON public.marketplace_profiles
  FOR INSERT TO authenticated
  WITH CHECK (user_id = auth.uid());

DROP POLICY IF EXISTS "mp_owner_update" ON public.marketplace_profiles;
CREATE POLICY "mp_owner_update" ON public.marketplace_profiles
  FOR UPDATE TO authenticated
  USING (user_id = auth.uid())
  WITH CHECK (user_id = auth.uid());

DROP POLICY IF EXISTS "mp_admin_all" ON public.marketplace_profiles;
CREATE POLICY "mp_admin_all" ON public.marketplace_profiles
  FOR ALL TO authenticated
  USING (public.marketplace_is_admin())
  WITH CHECK (public.marketplace_is_admin());

-- marketplace_crew_details
DROP POLICY IF EXISTS "mcd_public_read" ON public.marketplace_crew_details;
CREATE POLICY "mcd_public_read" ON public.marketplace_crew_details
  FOR SELECT TO public
  USING (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.status = 'active'
  ));

DROP POLICY IF EXISTS "mcd_owner_all" ON public.marketplace_crew_details;
CREATE POLICY "mcd_owner_all" ON public.marketplace_crew_details
  FOR ALL TO authenticated
  USING (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.user_id = auth.uid()
  ))
  WITH CHECK (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.user_id = auth.uid()
  ));

DROP POLICY IF EXISTS "mcd_admin_all" ON public.marketplace_crew_details;
CREATE POLICY "mcd_admin_all" ON public.marketplace_crew_details
  FOR ALL TO authenticated
  USING (public.marketplace_is_admin())
  WITH CHECK (public.marketplace_is_admin());

-- marketplace_vendor_details
DROP POLICY IF EXISTS "mvd_public_read" ON public.marketplace_vendor_details;
CREATE POLICY "mvd_public_read" ON public.marketplace_vendor_details
  FOR SELECT TO public
  USING (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.status = 'active'
  ));

DROP POLICY IF EXISTS "mvd_owner_all" ON public.marketplace_vendor_details;
CREATE POLICY "mvd_owner_all" ON public.marketplace_vendor_details
  FOR ALL TO authenticated
  USING (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.user_id = auth.uid()
  ))
  WITH CHECK (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.user_id = auth.uid()
  ));

DROP POLICY IF EXISTS "mvd_admin_all" ON public.marketplace_vendor_details;
CREATE POLICY "mvd_admin_all" ON public.marketplace_vendor_details
  FOR ALL TO authenticated
  USING (public.marketplace_is_admin())
  WITH CHECK (public.marketplace_is_admin());

-- marketplace_jobs
DROP POLICY IF EXISTS "mj_public_read_active" ON public.marketplace_jobs;
CREATE POLICY "mj_public_read_active" ON public.marketplace_jobs
  FOR SELECT TO public
  USING (status = 'active');

DROP POLICY IF EXISTS "mj_owner_all" ON public.marketplace_jobs;
CREATE POLICY "mj_owner_all" ON public.marketplace_jobs
  FOR ALL TO authenticated
  USING (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.user_id = auth.uid()
  ))
  WITH CHECK (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.user_id = auth.uid()
  ));

DROP POLICY IF EXISTS "mj_admin_all" ON public.marketplace_jobs;
CREATE POLICY "mj_admin_all" ON public.marketplace_jobs
  FOR ALL TO authenticated
  USING (public.marketplace_is_admin())
  WITH CHECK (public.marketplace_is_admin());

-- marketplace_gigs
DROP POLICY IF EXISTS "mg_public_read_active" ON public.marketplace_gigs;
CREATE POLICY "mg_public_read_active" ON public.marketplace_gigs
  FOR SELECT TO public
  USING (status = 'active');

DROP POLICY IF EXISTS "mg_owner_all" ON public.marketplace_gigs;
CREATE POLICY "mg_owner_all" ON public.marketplace_gigs
  FOR ALL TO authenticated
  USING (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.user_id = auth.uid()
  ))
  WITH CHECK (EXISTS (
    SELECT 1 FROM public.marketplace_profiles mp
    WHERE mp.id = profile_id AND mp.user_id = auth.uid()
  ));

DROP POLICY IF EXISTS "mg_admin_all" ON public.marketplace_gigs;
CREATE POLICY "mg_admin_all" ON public.marketplace_gigs
  FOR ALL TO authenticated
  USING (public.marketplace_is_admin())
  WITH CHECK (public.marketplace_is_admin());

-- ── TRIGGERS ─────────────────────────────────────────────────
DROP TRIGGER IF EXISTS marketplace_profiles_updated_at ON public.marketplace_profiles;
CREATE TRIGGER marketplace_profiles_updated_at
  BEFORE UPDATE ON public.marketplace_profiles
  FOR EACH ROW EXECUTE FUNCTION public.marketplace_set_updated_at();

DROP TRIGGER IF EXISTS marketplace_crew_updated_at ON public.marketplace_crew_details;
CREATE TRIGGER marketplace_crew_updated_at
  BEFORE UPDATE ON public.marketplace_crew_details
  FOR EACH ROW EXECUTE FUNCTION public.marketplace_set_updated_at();

DROP TRIGGER IF EXISTS marketplace_vendor_updated_at ON public.marketplace_vendor_details;
CREATE TRIGGER marketplace_vendor_updated_at
  BEFORE UPDATE ON public.marketplace_vendor_details
  FOR EACH ROW EXECUTE FUNCTION public.marketplace_set_updated_at();

-- ── STORAGE BUCKETS (via SQL) ─────────────────────────────────
INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
VALUES
  ('marketplace-headshots', 'marketplace-headshots', true, 5242880,
   ARRAY['image/jpeg','image/jpg','image/png','image/webp']::TEXT[]),
  ('marketplace-logos', 'marketplace-logos', true, 5242880,
   ARRAY['image/jpeg','image/jpg','image/png','image/webp','image/svg+xml']::TEXT[]),
  ('marketplace-resumes', 'marketplace-resumes', false, 10485760,
   ARRAY['application/pdf','application/msword',
         'application/vnd.openxmlformats-officedocument.wordprocessingml.document']::TEXT[])
ON CONFLICT (id) DO NOTHING;

-- Storage RLS
DROP POLICY IF EXISTS "marketplace_headshots_public_read" ON storage.objects;
CREATE POLICY "marketplace_headshots_public_read" ON storage.objects
  FOR SELECT TO public
  USING (bucket_id = 'marketplace-headshots');

DROP POLICY IF EXISTS "marketplace_headshots_auth_write" ON storage.objects;
CREATE POLICY "marketplace_headshots_auth_write" ON storage.objects
  FOR INSERT TO authenticated
  WITH CHECK (bucket_id = 'marketplace-headshots');

DROP POLICY IF EXISTS "marketplace_logos_public_read" ON storage.objects;
CREATE POLICY "marketplace_logos_public_read" ON storage.objects
  FOR SELECT TO public
  USING (bucket_id = 'marketplace-logos');

DROP POLICY IF EXISTS "marketplace_logos_auth_write" ON storage.objects;
CREATE POLICY "marketplace_logos_auth_write" ON storage.objects
  FOR INSERT TO authenticated
  WITH CHECK (bucket_id = 'marketplace-logos');

DROP POLICY IF EXISTS "marketplace_resumes_auth_read" ON storage.objects;
CREATE POLICY "marketplace_resumes_auth_read" ON storage.objects
  FOR SELECT TO authenticated
  USING (bucket_id = 'marketplace-resumes' AND auth.uid()::TEXT = (storage.foldername(name))[1]);

DROP POLICY IF EXISTS "marketplace_resumes_auth_write" ON storage.objects;
CREATE POLICY "marketplace_resumes_auth_write" ON storage.objects
  FOR INSERT TO authenticated
  WITH CHECK (bucket_id = 'marketplace-resumes');
