-- ============================================
-- RLS策略全面修复
-- 修复所有不符合设计规范的权限问题
-- ============================================

-- ============================================
-- 1. 修复 production_plans 表的严重安全漏洞
-- 问题：20260527_114150_fix_import_plan_select_rls.sql 中的策略过于宽松
-- 允许任何登录用户查看所有有关联的计划
-- ============================================

DROP POLICY IF EXISTS users_select_plans ON production_plans;

-- 正确的策略：采购商只能查看自己的计划，工厂只能查看关联的计划
CREATE POLICY purchaser_select_own_plans ON production_plans
  FOR SELECT USING (
    purchaser_id = get_user_master_company_id()
  );

CREATE POLICY factory_select_linked_plans ON production_plans
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM plan_factories
      WHERE plan_factories.plan_id = production_plans.id
      AND plan_factories.factory_id = get_user_master_company_id()
    )
  );

-- 分享链接导入时的临时访问（通过 share_links 表验证）
CREATE POLICY factory_select_via_share_link ON production_plans
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM share_links
      WHERE share_links.plan_id = production_plans.id
      AND share_links.short_code IS NOT NULL
      AND (share_links.expires_at IS NULL OR share_links.expires_at > NOW())
    )
  );

-- ============================================
-- 2. 修复 companies 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_companies ON companies;
DROP POLICY IF EXISTS purchaser_select_linked_companies ON companies;
DROP POLICY IF EXISTS factory_select_linked_companies ON companies;

-- 用户可以查看自己的公司
CREATE POLICY users_select_own_company ON companies
  FOR SELECT USING (
    id = get_user_master_company_id()
  );

-- 采购商可以查看已建立合作关系的工厂
CREATE POLICY purchaser_select_linked_factories ON companies
  FOR SELECT USING (
    role IN ('textile', 'washing')
    AND EXISTS (
      SELECT 1 FROM company_relationships
      WHERE company_relationships.purchaser_company_id = get_user_master_company_id()
      AND company_relationships.factory_company_id = companies.id
      AND company_relationships.status = 'active'
    )
  );

-- 工厂可以查看已建立合作关系的采购商
CREATE POLICY factory_select_linked_purchasers ON companies
  FOR SELECT USING (
    role = 'purchaser'
    AND EXISTS (
      SELECT 1 FROM company_relationships
      WHERE company_relationships.factory_company_id = get_user_master_company_id()
      AND company_relationships.purchaser_company_id = companies.id
      AND company_relationships.status = 'active'
    )
  );

-- ============================================
-- 3. 修复 profiles 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_profiles ON profiles;
DROP POLICY IF EXISTS anon_insert_profiles ON profiles;

-- 用户可以查看自己公司的所有成员
CREATE POLICY users_select_company_profiles ON profiles
  FOR SELECT USING (
    company_id = get_user_master_company_id()
    OR id = auth.uid()
  );

-- 用户只能插入自己的profile
CREATE POLICY users_insert_own_profile ON profiles
  FOR INSERT WITH CHECK (
    id = auth.uid()
  );

-- ============================================
-- 4. 修复 company_members 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_company_members ON company_members;
DROP POLICY IF EXISTS anon_insert_company_members ON company_members;

-- 只能查看自己公司的成员
CREATE POLICY users_select_company_members ON company_members
  FOR SELECT USING (
    company_id = get_user_master_company_id()
  );

-- 只能给自己公司添加成员
CREATE POLICY users_insert_company_members ON company_members
  FOR INSERT WITH CHECK (
    company_id = get_user_master_company_id()
  );

-- ============================================
-- 5. 修复 yarn_ratios 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_yarn_ratios ON yarn_ratios;
DROP POLICY IF EXISTS anon_insert_yarn_ratios ON yarn_ratios;
DROP POLICY IF EXISTS anon_delete_yarn_ratios ON yarn_ratios;

-- 查看权限：计划的采购商或关联工厂可以查看
CREATE POLICY users_select_yarn_ratios ON yarn_ratios
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM production_plans
      WHERE id = yarn_ratios.plan_id
      AND (
        purchaser_id = get_user_master_company_id()
        OR EXISTS (
          SELECT 1 FROM plan_factories
          WHERE plan_id = production_plans.id
          AND factory_id = get_user_master_company_id()
        )
      )
    )
  );

-- 插入权限：只有计划的采购商可以插入
CREATE POLICY users_insert_yarn_ratios ON yarn_ratios
  FOR INSERT WITH CHECK (
    EXISTS (
      SELECT 1 FROM production_plans
      WHERE id = yarn_ratios.plan_id
      AND purchaser_id = get_user_master_company_id()
    )
  );

-- 删除权限：只有计划的采购商可以删除
CREATE POLICY users_delete_yarn_ratios ON yarn_ratios
  FOR DELETE USING (
    EXISTS (
      SELECT 1 FROM production_plans
      WHERE id = yarn_ratios.plan_id
      AND purchaser_id = get_user_master_company_id()
    )
  );

-- ============================================
-- 6. 修复 warehouses 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_warehouses ON warehouses;
DROP POLICY IF EXISTS anon_insert_warehouses ON warehouses;
DROP POLICY IF EXISTS anon_update_warehouses ON warehouses;

-- 只能查看自己公司的仓库
CREATE POLICY users_select_company_warehouses ON warehouses
  FOR SELECT USING (
    company_id = get_user_master_company_id()
  );

-- 只能插入自己公司的仓库
CREATE POLICY users_insert_company_warehouses ON warehouses
  FOR INSERT WITH CHECK (
    company_id = get_user_master_company_id()
  );

-- 只能更新自己公司的仓库
CREATE POLICY users_update_company_warehouses ON warehouses
  FOR UPDATE USING (
    company_id = get_user_master_company_id()
  );

-- ============================================
-- 7. 修复 inventory_records 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_inventory ON inventory_records;
DROP POLICY IF EXISTS anon_insert_inventory ON inventory_records;

-- 查看权限：通过仓库关联到公司
CREATE POLICY users_select_company_inventory ON inventory_records
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM warehouses
      WHERE id = warehouse_id
      AND company_id = get_user_master_company_id()
    )
    OR EXISTS (
      SELECT 1 FROM production_plans p
      JOIN plan_factories pf ON p.id = pf.plan_id
      WHERE p.id = inventory_records.plan_id
      AND (p.purchaser_id = get_user_master_company_id() OR pf.factory_id = get_user_master_company_id())
    )
  );

-- 插入权限：通过仓库验证
CREATE POLICY users_insert_company_inventory ON inventory_records
  FOR INSERT WITH CHECK (
    EXISTS (
      SELECT 1 FROM warehouses
      WHERE id = warehouse_id
      AND company_id = get_user_master_company_id()
    )
  );

-- ============================================
-- 8. 修复 yarn_stock 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_yarn_stock ON yarn_stock;
DROP POLICY IF EXISTS anon_insert_yarn_stock ON yarn_stock;
DROP POLICY IF EXISTS anon_update_yarn_stock ON yarn_stock;

-- 只能查看自己公司的纱线库存
CREATE POLICY users_select_company_yarn_stock ON yarn_stock
  FOR SELECT USING (
    company_id = get_user_master_company_id()
  );

-- 只能插入自己公司的纱线库存
CREATE POLICY users_insert_company_yarn_stock ON yarn_stock
  FOR INSERT WITH CHECK (
    company_id = get_user_master_company_id()
  );

-- 只能更新自己公司的纱线库存
CREATE POLICY users_update_company_yarn_stock ON yarn_stock
  FOR UPDATE USING (
    company_id = get_user_master_company_id()
  );

-- ============================================
-- 9. 修复 plan_process_steps 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_process_steps ON plan_process_steps;
DROP POLICY IF EXISTS anon_insert_process_steps ON plan_process_steps;
DROP POLICY IF EXISTS anon_update_process_steps ON plan_process_steps;

-- 查看权限：计划的采购商或关联工厂可以查看
CREATE POLICY users_select_process_steps ON plan_process_steps
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM production_plans
      LEFT JOIN plan_factories ON production_plans.id = plan_factories.plan_id
      WHERE production_plans.id = plan_process_steps.plan_id
      AND (
        production_plans.purchaser_id = get_user_master_company_id()
        OR plan_factories.factory_id = get_user_master_company_id()
      )
    )
  );

-- 插入权限：计划的采购商或关联工厂可以插入
CREATE POLICY users_insert_process_steps ON plan_process_steps
  FOR INSERT WITH CHECK (
    EXISTS (
      SELECT 1 FROM production_plans
      LEFT JOIN plan_factories ON production_plans.id = plan_factories.plan_id
      WHERE production_plans.id = plan_process_steps.plan_id
      AND (
        production_plans.purchaser_id = get_user_master_company_id()
        OR plan_factories.factory_id = get_user_master_company_id()
      )
    )
  );

-- 更新权限：计划的采购商或关联工厂可以更新
CREATE POLICY users_update_process_steps ON plan_process_steps
  FOR UPDATE USING (
    EXISTS (
      SELECT 1 FROM production_plans
      LEFT JOIN plan_factories ON production_plans.id = plan_factories.plan_id
      WHERE production_plans.id = plan_process_steps.plan_id
      AND (
        production_plans.purchaser_id = get_user_master_company_id()
        OR plan_factories.factory_id = get_user_master_company_id()
      )
    )
  );

-- ============================================
-- 10. 修复 payments 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_payments ON payments;
DROP POLICY IF EXISTS anon_insert_payments ON payments;
DROP POLICY IF EXISTS anon_update_payments ON payments;

-- 查看权限：付款方或收款方可以查看
CREATE POLICY users_select_payments ON payments
  FOR SELECT USING (
    from_company_id = get_user_master_company_id()
    OR to_company_id = get_user_master_company_id()
  );

-- 插入权限：付款方可以插入
CREATE POLICY users_insert_payments ON payments
  FOR INSERT WITH CHECK (
    from_company_id = get_user_master_company_id()
    OR to_company_id = get_user_master_company_id()
  );

-- 更新权限：付款方或收款方可以更新
CREATE POLICY users_update_payments ON payments
  FOR UPDATE USING (
    from_company_id = get_user_master_company_id()
    OR to_company_id = get_user_master_company_id()
  );

-- ============================================
-- 11. 修复 plan_factories 表的权限问题
-- ============================================

DROP POLICY IF EXISTS anon_select_plan_factories ON plan_factories;
DROP POLICY IF EXISTS anon_insert_plan_factories ON plan_factories;
DROP POLICY IF EXISTS anon_delete_plan_factories ON plan_factories;

-- 工厂可以查看关联到自己的计划
CREATE POLICY factory_select_plan_factories ON plan_factories
  FOR SELECT USING (
    factory_id = get_user_master_company_id()
  );

-- 采购商可以查看自己计划的工厂关联
CREATE POLICY purchaser_select_plan_factories ON plan_factories
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM production_plans
      WHERE id = plan_id
      AND purchaser_id = get_user_master_company_id()
    )
  );

-- 采购商可以创建工厂关联
CREATE POLICY purchaser_insert_plan_factories ON plan_factories
  FOR INSERT WITH CHECK (
    EXISTS (
      SELECT 1 FROM production_plans
      WHERE id = plan_id
      AND purchaser_id = get_user_master_company_id()
    )
  );

-- 采购商可以删除工厂关联
CREATE POLICY purchaser_delete_plan_factories ON plan_factories
  FOR DELETE USING (
    EXISTS (
      SELECT 1 FROM production_plans
      WHERE id = plan_id
      AND purchaser_id = get_user_master_company_id()
    )
  );

-- 工厂可以创建关联（通过分享链接导入时）
CREATE POLICY factory_insert_plan_factories ON plan_factories
  FOR INSERT WITH CHECK (
    factory_id = get_user_master_company_id()
  );

-- ============================================
-- 12. 修复 share_links 表的权限问题
-- ============================================

DROP POLICY IF EXISTS share_links_select ON share_links;

-- 创建者可以查看自己的分享链接
-- 有合作关系的公司可以查看相关分享链接
CREATE POLICY users_select_share_links ON share_links
  FOR SELECT USING (
    created_by = auth.uid()
    OR EXISTS (
      SELECT 1 FROM profiles p
      WHERE p.id = auth.uid()
      AND p.company_id IN (
        SELECT purchaser_company_id FROM company_relationships
        WHERE factory_company_id = p.company_id
      )
    )
    OR short_code IS NOT NULL
  );

-- ============================================
-- 13. 确保所有表都有RLS启用
-- ============================================

ALTER TABLE companies ENABLE ROW LEVEL SECURITY;
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE company_members ENABLE ROW LEVEL SECURITY;
ALTER TABLE production_plans ENABLE ROW LEVEL SECURITY;
ALTER TABLE plan_factories ENABLE ROW LEVEL SECURITY;
ALTER TABLE yarn_ratios ENABLE ROW LEVEL SECURITY;
ALTER TABLE warehouses ENABLE ROW LEVEL SECURITY;
ALTER TABLE inventory_records ENABLE ROW LEVEL SECURITY;
ALTER TABLE yarn_stock ENABLE ROW LEVEL SECURITY;
ALTER TABLE plan_process_steps ENABLE ROW LEVEL SECURITY;
ALTER TABLE payments ENABLE ROW LEVEL SECURITY;
ALTER TABLE share_links ENABLE ROW LEVEL SECURITY;
ALTER TABLE company_relationships ENABLE ROW LEVEL SECURITY;
ALTER TABLE products ENABLE ROW LEVEL SECURITY;
ALTER TABLE product_inventory_records ENABLE ROW LEVEL SECURITY;
ALTER TABLE product_yarn_ratios ENABLE ROW LEVEL SECURITY;
ALTER TABLE product_price_history ENABLE ROW LEVEL SECURITY;
ALTER TABLE product_outbound_records ENABLE ROW LEVEL SECURITY;
ALTER TABLE production_price_history ENABLE ROW LEVEL SECURITY;
ALTER TABLE washing_plans ENABLE ROW LEVEL SECURITY;
ALTER TABLE washing_process_steps ENABLE ROW LEVEL SECURITY;
ALTER TABLE washing_plan_completions ENABLE ROW LEVEL SECURITY;
ALTER TABLE finished_products ENABLE ROW LEVEL SECURITY;
ALTER TABLE finished_product_inventory_records ENABLE ROW LEVEL SECURITY;
ALTER TABLE yarn_stock_records ENABLE ROW LEVEL SECURITY;
ALTER TABLE accounts_payable ENABLE ROW LEVEL SECURITY;
ALTER TABLE accounts_payable_items ENABLE ROW LEVEL SECURITY;
ALTER TABLE notifications ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_feedback ENABLE ROW LEVEL SECURITY;
ALTER TABLE crash_reports ENABLE ROW LEVEL SECURITY;
ALTER TABLE audit_logs ENABLE ROW LEVEL SECURITY;
