-- Database Schema Fixes and Optimizations
-- Generated: 2026-01-16

-- ==========================================
-- 1. ADD MISSING COLUMNS
-- ==========================================

-- Add missing timestamps to products if not exists
DO $$ 
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.columns 
    WHERE table_name = 'products' AND column_name = 'deleted_at'
  ) THEN
    ALTER TABLE products ADD COLUMN deleted_at TIMESTAMP;
  END IF;
END $$;

-- Add missing order columns
DO $$ 
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.columns 
    WHERE table_name = 'orders' AND column_name = 'customer_id'
  ) THEN
    ALTER TABLE orders ADD COLUMN customer_id UUID;
    ALTER TABLE orders ADD CONSTRAINT fk_orders_customer 
      FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE SET NULL;
  END IF;
END $$;

DO $$ 
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.columns 
    WHERE table_name = 'orders' AND column_name = 'shipping_address'
  ) THEN
    ALTER TABLE orders ADD COLUMN shipping_address JSONB;
    ALTER TABLE orders ADD COLUMN billing_address JSONB;
    ALTER TABLE orders ADD COLUMN payment_method VARCHAR(50);
    ALTER TABLE orders ADD COLUMN tracking_number VARCHAR(100);
    ALTER TABLE orders ADD COLUMN notes TEXT;
    ALTER TABLE orders ADD COLUMN created_at TIMESTAMP DEFAULT NOW();
  END IF;
END $$;

-- ==========================================
-- 2. FIX DATA TYPE INCONSISTENCIES
-- ==========================================

-- Ensure consistent boolean defaults
ALTER TABLE products ALTER COLUMN isfeatured SET DEFAULT false;
ALTER TABLE products ALTER COLUMN isbestseller SET DEFAULT false;
ALTER TABLE products ALTER COLUMN isactive SET DEFAULT true;

ALTER TABLE product_images ALTER COLUMN is_primary SET DEFAULT false;
ALTER TABLE product_images ALTER COLUMN display_order SET DEFAULT 0;
ALTER TABLE product_images ALTER COLUMN variant_stock SET DEFAULT 0;

ALTER TABLE blogposts ALTER COLUMN ispublished SET DEFAULT false;
ALTER TABLE blogposts ALTER COLUMN isactive SET DEFAULT true;

ALTER TABLE pages ALTER COLUMN ispublished SET DEFAULT true;
ALTER TABLE pages ALTER COLUMN isactive SET DEFAULT true;

ALTER TABLE portfolioprojects ALTER COLUMN isactive SET DEFAULT true;

-- ==========================================
-- 3. ADD MISSING INDEXES FOR PERFORMANCE
-- ==========================================

-- Products: Add indexes for common queries
CREATE INDEX IF NOT EXISTS idx_products_active_bestseller 
  ON products(isactive, isbestseller) WHERE isactive = true AND isbestseller = true;

CREATE INDEX IF NOT EXISTS idx_products_category_active 
  ON products(category, isactive) WHERE isactive = true;

CREATE INDEX IF NOT EXISTS idx_products_price_range 
  ON products(price) WHERE isactive = true;

CREATE INDEX IF NOT EXISTS idx_products_stock 
  ON products(stockquantity) WHERE isactive = true;

-- Product Images: Optimize joins
CREATE INDEX IF NOT EXISTS idx_product_images_product_order 
  ON product_images(product_id, display_order);

-- Blog: Add missing indexes
CREATE INDEX IF NOT EXISTS idx_blogposts_published_date 
  ON blogposts(publisheddate DESC) WHERE ispublished = true;

CREATE INDEX IF NOT EXISTS idx_blogposts_category 
  ON blogposts(category) WHERE ispublished = true;

-- Pages: Add index for active lookup
CREATE INDEX IF NOT EXISTS idx_pages_slug_active 
  ON pages(slug) WHERE isactive = true AND ispublished = true;

-- Orders: Add indexes for queries
CREATE INDEX IF NOT EXISTS idx_orders_customer 
  ON orders(customer_id) WHERE customer_id IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_orders_status 
  ON orders(orderstatus);

CREATE INDEX IF NOT EXISTS idx_orders_date 
  ON orders(orderdate DESC);

CREATE INDEX IF NOT EXISTS idx_orders_number 
  ON orders(ordernumber);

-- Customers: Add indexes
CREATE INDEX IF NOT EXISTS idx_customers_email_active 
  ON customers(email) WHERE is_active = true;

CREATE INDEX IF NOT EXISTS idx_customers_created 
  ON customers(created_at DESC);

-- ==========================================
-- 4. ADD MISSING CONSTRAINTS
-- ==========================================

-- Ensure products have valid prices
DO $$ 
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.table_constraints 
    WHERE constraint_name = 'chk_products_price_positive'
  ) THEN
    ALTER TABLE products ADD CONSTRAINT chk_products_price_positive 
      CHECK (price >= 0);
  END IF;
END $$;

DO $$ 
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.table_constraints 
    WHERE constraint_name = 'chk_products_stock_nonnegative'
  ) THEN
    ALTER TABLE products ADD CONSTRAINT chk_products_stock_nonnegative 
      CHECK (stockquantity >= 0);
  END IF;
END $$;

-- Ensure product images have valid ordering
DO $$ 
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.table_constraints 
    WHERE constraint_name = 'chk_product_images_order_nonnegative'
  ) THEN
    ALTER TABLE product_images ADD CONSTRAINT chk_product_images_order_nonnegative 
      CHECK (display_order >= 0);
  END IF;
END $$;

DO $$ 
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.table_constraints 
    WHERE constraint_name = 'chk_product_images_stock_nonnegative'
  ) THEN
    ALTER TABLE product_images ADD CONSTRAINT chk_product_images_stock_nonnegative 
      CHECK (variant_stock >= 0);
  END IF;
END $$;

-- Ensure orders have valid amounts
ALTER TABLE orders DROP CONSTRAINT IF EXISTS chk_orders_amounts;
ALTER TABLE orders ADD CONSTRAINT chk_orders_amounts 
  CHECK (subtotal >= 0 AND total >= 0);

-- ==========================================
-- 5. ADD CASCADE DELETE FOR ORPHANED DATA
-- ==========================================

-- Ensure product images are deleted when product is deleted
ALTER TABLE product_images DROP CONSTRAINT IF EXISTS product_images_product_id_fkey;
ALTER TABLE product_images ADD CONSTRAINT product_images_product_id_fkey 
  FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE;

-- ==========================================
-- 6. CREATE MISSING TABLES
-- ==========================================

-- Create order_items if missing
CREATE TABLE IF NOT EXISTS order_items (
  id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::TEXT,
  order_id TEXT NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
  product_id TEXT REFERENCES products(id) ON DELETE SET NULL,
  product_name VARCHAR(255) NOT NULL,
  product_sku VARCHAR(100),
  quantity INTEGER NOT NULL CHECK (quantity > 0),
  unit_price NUMERIC(10,2) NOT NULL CHECK (unit_price >= 0),
  total_price NUMERIC(10,2) NOT NULL CHECK (total_price >= 0),
  color_variant VARCHAR(100),
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_order_items_order ON order_items(order_id);
CREATE INDEX IF NOT EXISTS idx_order_items_product ON order_items(product_id);

-- Create reviews table if missing
CREATE TABLE IF NOT EXISTS product_reviews (
  id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::TEXT,
  product_id TEXT NOT NULL REFERENCES products(id) ON DELETE CASCADE,
  customer_id UUID REFERENCES customers(id) ON DELETE CASCADE,
  rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
  title VARCHAR(200),
  comment TEXT,
  is_verified_purchase BOOLEAN DEFAULT false,
  is_approved BOOLEAN DEFAULT false,
  helpful_count INTEGER DEFAULT 0,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_reviews_product ON product_reviews(product_id);
CREATE INDEX IF NOT EXISTS idx_reviews_customer ON product_reviews(customer_id);
CREATE INDEX IF NOT EXISTS idx_reviews_approved ON product_reviews(is_approved) WHERE is_approved = true;

-- ==========================================
-- 7. ADD TRIGGERS FOR AUTOMATIC TIMESTAMPS
-- ==========================================

-- Function to update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updatedat = NOW();
  RETURN NEW;
END;
$$ language 'plpgsql';

-- Add triggers for products
DROP TRIGGER IF EXISTS update_products_updatedat ON products;
CREATE TRIGGER update_products_updatedat 
  BEFORE UPDATE ON products 
  FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Add triggers for blogposts
DROP TRIGGER IF EXISTS update_blogposts_updatedat ON blogposts;
CREATE TRIGGER update_blogposts_updatedat 
  BEFORE UPDATE ON blogposts 
  FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Add triggers for pages
DROP TRIGGER IF EXISTS update_pages_updatedat ON pages;
CREATE TRIGGER update_pages_updatedat 
  BEFORE UPDATE ON pages 
  FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- ==========================================
-- 8. UPDATE STATISTICS FOR QUERY PLANNER
-- ==========================================

ANALYZE products;
ANALYZE product_images;
ANALYZE blogposts;
ANALYZE pages;
ANALYZE portfolioprojects;
ANALYZE orders;
ANALYZE customers;

-- ==========================================
-- COMPLETE
-- ==========================================

SELECT 'Database schema fixes applied successfully!' AS status;
