-- RLS Policies and Seeding Script for Hoteles Estelar Variable Remuneration System
SET app.current_user_role = 'admin';

-- ==========================================
-- 0. TEMPORARILY DISABLE RLS FOR SEEDING
-- ==========================================
ALTER TABLE "regions" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "hotels" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "goals" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "sales_results" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "settlements" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "audit_logs" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "compensation_plans" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "calculation_rules" DISABLE ROW LEVEL SECURITY;

-- ==========================================
-- 1. CLEAN UP OLD POLICIES
-- ==========================================
DROP POLICY IF EXISTS audit_logs_insert_policy ON "audit_logs";
DROP POLICY IF EXISTS audit_logs_select_policy ON "audit_logs";
DROP POLICY IF EXISTS regions_select_policy ON "regions";
DROP POLICY IF EXISTS regions_modify_policy ON "regions";
DROP POLICY IF EXISTS hotels_select_policy ON "hotels";
DROP POLICY IF EXISTS hotels_modify_policy ON "hotels";
DROP POLICY IF EXISTS users_select_policy ON "users";
DROP POLICY IF EXISTS users_modify_policy ON "users";
DROP POLICY IF EXISTS goals_select_policy ON "goals";
DROP POLICY IF EXISTS goals_modify_policy ON "goals";
DROP POLICY IF EXISTS sales_results_select_policy ON "sales_results";
DROP POLICY IF EXISTS sales_results_modify_policy ON "sales_results";
DROP POLICY IF EXISTS settlements_select_policy ON "settlements";
DROP POLICY IF EXISTS settlements_modify_policy ON "settlements";
DROP POLICY IF EXISTS plans_select_policy ON "compensation_plans";
DROP POLICY IF EXISTS plans_modify_policy ON "compensation_plans";
DROP POLICY IF EXISTS rules_select_policy ON "calculation_rules";
DROP POLICY IF EXISTS rules_modify_policy ON "calculation_rules";

-- ==========================================
-- 2. SEED DATA
-- ==========================================

-- Seed Regions
INSERT INTO "regions" ("name", "code") VALUES
('Bogotá', 'BOG'),
('Antioquia', 'ANT'),
('Caribe', 'CAR')
ON CONFLICT ("code") DO NOTHING;

-- Seed Hotels
INSERT INTO "hotels" ("name", "code", "region_id", "status") VALUES
('Estelar Parque de la 93', 'EST-P93', (SELECT id FROM regions WHERE code = 'BOG'), 'ACTIVE'),
('Estelar Medellin', 'EST-MDE', (SELECT id FROM regions WHERE code = 'ANT'), 'ACTIVE'),
('Estelar Cartagena', 'EST-CTG', (SELECT id FROM regions WHERE code = 'CAR'), 'ACTIVE')
ON CONFLICT ("code") DO NOTHING;

-- Seed Users
-- password_hash is bcrypt hash of 'password123'
INSERT INTO "users" ("username", "email", "password_hash", "role", "hotel_id", "area", "status", "created_at") VALUES
('admin', 'admin@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'admin', (SELECT id FROM hotels WHERE code = 'EST-P93'), 'Sistemas', 'ACTIVE', NOW()),
('director', 'director@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'director', (SELECT id FROM hotels WHERE code = 'EST-P93'), 'Comercial', 'ACTIVE', NOW()),
('gerente_mde', 'gerente.mde@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'hotel_manager', (SELECT id FROM hotels WHERE code = 'EST-MDE'), 'Administracion', 'ACTIVE', NOW()),
('gerente_ctg', 'gerente.ctg@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'hotel_manager', (SELECT id FROM hotels WHERE code = 'EST-CTG'), 'Administracion', 'ACTIVE', NOW()),
('lider_ctg', 'lider.ctg@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'commercial_leader', (SELECT id FROM hotels WHERE code = 'EST-CTG'), 'Ventas', 'ACTIVE', NOW()),
('lider_mde', 'lider.mde@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'commercial_leader', (SELECT id FROM hotels WHERE code = 'EST-MDE'), 'Ventas', 'ACTIVE', NOW()),
('analista', 'analista@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'analyst', (SELECT id FROM hotels WHERE code = 'EST-P93'), 'Finanzas', 'ACTIVE', NOW()),
('consulta', 'consulta@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'auditor', (SELECT id FROM hotels WHERE code = 'EST-P93'), 'Auditoria', 'ACTIVE', NOW()),
('colaborador_mde', 'colaborador.mde@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'collaborator', (SELECT id FROM hotels WHERE code = 'EST-MDE'), 'Ventas', 'ACTIVE', NOW()),
('colaborador_ctg', 'colaborador.ctg@estelar.com', '$2b$10$lRn/GrwzaEGxWqqQGGz0f.44nBywObKkGWRajlxWeDGZ3o4f7ayjy', 'collaborator', (SELECT id FROM hotels WHERE code = 'EST-CTG'), 'Ventas', 'ACTIVE', NOW())
ON CONFLICT ("username") DO UPDATE SET role = EXCLUDED.role;


-- ==========================================
-- 3. ENABLE ROW-LEVEL SECURITY
-- ==========================================

ALTER TABLE "regions" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "hotels" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "goals" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "sales_results" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "settlements" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "audit_logs" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "compensation_plans" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "calculation_rules" ENABLE ROW LEVEL SECURITY;

ALTER TABLE "regions" FORCE ROW LEVEL SECURITY;
ALTER TABLE "hotels" FORCE ROW LEVEL SECURITY;
ALTER TABLE "users" FORCE ROW LEVEL SECURITY;
ALTER TABLE "goals" FORCE ROW LEVEL SECURITY;
ALTER TABLE "sales_results" FORCE ROW LEVEL SECURITY;
ALTER TABLE "settlements" FORCE ROW LEVEL SECURITY;
ALTER TABLE "audit_logs" FORCE ROW LEVEL SECURITY;
ALTER TABLE "compensation_plans" FORCE ROW LEVEL SECURITY;
ALTER TABLE "calculation_rules" FORCE ROW LEVEL SECURITY;


-- ==========================================
-- 4. CREATE RLS POLICIES
-- ==========================================

-- A. Audit Logs Policies (Insert allowed for all, Select only for Admin/Analista, No Updates/Deletes)
CREATE POLICY audit_logs_insert_policy ON "audit_logs"
  FOR INSERT WITH CHECK (true);

CREATE POLICY audit_logs_select_policy ON "audit_logs"
  FOR SELECT USING (
    current_setting('app.current_user_role', true) IN ('admin', 'analyst')
    OR user_id = NULLIF(current_setting('app.current_user_id', true), '')::integer
  );


-- B. Regions Policies
CREATE POLICY regions_select_policy ON "regions"
  FOR SELECT USING (
    current_setting('app.current_user_role', true) IN ('admin', 'analyst', 'director')
    OR id = NULLIF(current_setting('app.current_region_id', true), '')::integer
  );

CREATE POLICY regions_modify_policy ON "regions"
  FOR ALL USING (current_setting('app.current_user_role', true) IN ('admin', 'director'));


-- C. Hotels Policies
CREATE POLICY hotels_select_policy ON "hotels"
  FOR SELECT USING (
    current_setting('app.current_user_role', true) IN ('admin', 'analyst', 'director')
    OR region_id = NULLIF(current_setting('app.current_region_id', true), '')::integer
    OR id = NULLIF(current_setting('app.current_hotel_id', true), '')::integer
  );

CREATE POLICY hotels_modify_policy ON "hotels"
  FOR ALL USING (current_setting('app.current_user_role', true) IN ('admin', 'director'));


-- D. Users Policies
CREATE POLICY users_select_policy ON "users"
  FOR SELECT USING (
    current_setting('app.current_user_role', true) IN ('admin', 'analyst', 'director')
    OR (
      current_setting('app.current_user_role', true) = 'hotel_manager'
      AND hotel_id = NULLIF(current_setting('app.current_hotel_id', true), '')::integer
    )
    OR (
      current_setting('app.current_user_role', true) = 'commercial_leader'
      AND hotel_id IN (SELECT id FROM hotels WHERE region_id = NULLIF(current_setting('app.current_region_id', true), '')::integer)
    )
    OR id = NULLIF(current_setting('app.current_user_id', true), '')::integer
  );

CREATE POLICY users_modify_policy ON "users"
  FOR ALL USING (current_setting('app.current_user_role', true) = 'admin');


-- E. Goals Policies
CREATE POLICY goals_select_policy ON "goals"
  FOR SELECT USING (
    current_setting('app.current_user_role', true) IN ('admin', 'analyst', 'director')
    OR target_id = NULLIF(current_setting('app.current_user_id', true), '')::integer
    OR target_id IN (
      SELECT u.id FROM users u WHERE u.hotel_id = NULLIF(current_setting('app.current_hotel_id', true), '')::integer
    )
    OR target_id IN (
      SELECT u.id FROM users u JOIN hotels h ON u.hotel_id = h.id 
      WHERE h.region_id = NULLIF(current_setting('app.current_region_id', true), '')::integer
    )
  );

CREATE POLICY goals_modify_policy ON "goals"
  FOR ALL USING (current_setting('app.current_user_role', true) IN ('admin', 'director'));


-- F. Sales Results Policies
CREATE POLICY sales_results_select_policy ON "sales_results"
  FOR SELECT USING (
    current_setting('app.current_user_role', true) IN ('admin', 'analyst', 'director')
    OR user_id = NULLIF(current_setting('app.current_user_id', true), '')::integer
    OR hotel_id = NULLIF(current_setting('app.current_hotel_id', true), '')::integer
    OR hotel_id IN (
      SELECT id FROM hotels WHERE region_id = NULLIF(current_setting('app.current_region_id', true), '')::integer
    )
  );

CREATE POLICY sales_results_modify_policy ON "sales_results"
  FOR ALL USING (
    current_setting('app.current_user_role', true) IN ('admin', 'analyst')
    OR (
      current_setting('app.current_user_role', true) = 'commercial_leader'
      AND hotel_id IN (
        SELECT id FROM hotels WHERE region_id = NULLIF(current_setting('app.current_region_id', true), '')::integer
      )
    )
  );


-- G. Settlements Policies
CREATE POLICY settlements_select_policy ON "settlements"
  FOR SELECT USING (
    current_setting('app.current_user_role', true) IN ('admin', 'analyst', 'director')
    OR user_id = NULLIF(current_setting('app.current_user_id', true), '')::integer
    OR user_id IN (
      SELECT u.id FROM users u WHERE u.hotel_id = NULLIF(current_setting('app.current_hotel_id', true), '')::integer
    )
    OR user_id IN (
      SELECT u.id FROM users u JOIN hotels h ON u.hotel_id = h.id 
      WHERE h.region_id = NULLIF(current_setting('app.current_region_id', true), '')::integer
    )
  );

CREATE POLICY settlements_modify_policy ON "settlements"
  FOR ALL USING (
    current_setting('app.current_user_role', true) IN ('admin', 'analyst')
    OR (
      current_setting('app.current_user_role', true) = 'commercial_leader'
      AND user_id IN (
        SELECT u.id FROM users u JOIN hotels h ON u.hotel_id = h.id 
        WHERE h.region_id = NULLIF(current_setting('app.current_region_id', true), '')::integer
      )
    )
  );


-- H. Compensation Plans Policies
CREATE POLICY plans_select_policy ON "compensation_plans"
  FOR SELECT USING (true);

CREATE POLICY plans_modify_policy ON "compensation_plans"
  FOR ALL USING (current_setting('app.current_user_role', true) IN ('admin', 'director', 'analyst'));


-- I. Calculation Rules Policies
CREATE POLICY rules_select_policy ON "calculation_rules"
  FOR SELECT USING (true);

CREATE POLICY rules_modify_policy ON "calculation_rules"
  FOR ALL USING (current_setting('app.current_user_role', true) IN ('admin', 'director', 'analyst'));
