/**
 * Database Schema Setup Script
 * Run this script once to create all required tables
 * Usage: npm run db:setup
 */

require('dotenv').config();
const { pool } = require('./connection');

// SQL statements to create tables (matching Developer Guide Part 2)
const createTablesSQL = `
-- ============================================
-- TABLE: users
-- ============================================
CREATE TABLE IF NOT EXISTS users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    company_name VARCHAR(255),
    phone VARCHAR(20),
    email_verified BOOLEAN DEFAULT FALSE,
    verification_token VARCHAR(255),
    plan VARCHAR(50) DEFAULT 'free',
    plan_started_at TIMESTAMP,
    plan_expires_at TIMESTAMP,
    monthly_quota INTEGER DEFAULT 100,
    calls_this_month INTEGER DEFAULT 0,
    quota_reset_date DATE,
    razorpay_customer_id VARCHAR(100),
    razorpay_subscription_id VARCHAR(100),
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),
    last_login_at TIMESTAMP,
    is_active BOOLEAN DEFAULT TRUE
);

CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);

-- ============================================
-- TABLE: api_keys
-- ============================================
CREATE TABLE IF NOT EXISTS api_keys (
    id SERIAL PRIMARY KEY,
    user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
    key_prefix VARCHAR(20) NOT NULL,
    key_hash VARCHAR(255) NOT NULL,
    key_hint VARCHAR(10),
    name VARCHAR(100) DEFAULT 'Default',
    is_test_key BOOLEAN DEFAULT FALSE,
    is_active BOOLEAN DEFAULT TRUE,
    last_used_at TIMESTAMP,
    total_calls INTEGER DEFAULT 0,
    created_at TIMESTAMP DEFAULT NOW(),
    expires_at TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_api_keys_user ON api_keys(user_id);
CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash);

-- ============================================
-- TABLE: api_calls
-- ============================================
CREATE TABLE IF NOT EXISTS api_calls (
    id SERIAL PRIMARY KEY,
    user_id INTEGER REFERENCES users(id),
    api_key_id INTEGER REFERENCES api_keys(id),
    endpoint VARCHAR(100) NOT NULL,
    method VARCHAR(10) NOT NULL,
    request_params JSONB,
    response_status INTEGER,
    response_time_ms INTEGER,
    success BOOLEAN,
    error_message VARCHAR(500),
    credits_used INTEGER DEFAULT 1,
    is_billable BOOLEAN DEFAULT TRUE,
    ip_address VARCHAR(45),
    user_agent VARCHAR(500),
    called_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_api_calls_user ON api_calls(user_id);
CREATE INDEX IF NOT EXISTS idx_api_calls_date ON api_calls(called_at);
CREATE INDEX IF NOT EXISTS idx_api_calls_endpoint ON api_calls(endpoint);

-- ============================================
-- TABLE: ifsc_codes
-- ============================================
CREATE TABLE IF NOT EXISTS ifsc_codes (
    id SERIAL PRIMARY KEY,
    ifsc VARCHAR(11) UNIQUE NOT NULL,
    bank_name VARCHAR(255) NOT NULL,
    branch VARCHAR(255),
    address TEXT,
    city VARCHAR(100),
    district VARCHAR(100),
    state VARCHAR(100),
    contact VARCHAR(100),
    upi_enabled BOOLEAN DEFAULT FALSE,
    rtgs_enabled BOOLEAN DEFAULT TRUE,
    neft_enabled BOOLEAN DEFAULT TRUE,
    imps_enabled BOOLEAN DEFAULT TRUE,
    micr_code VARCHAR(20),
    swift_code VARCHAR(20),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_ifsc ON ifsc_codes(ifsc);

-- ============================================
-- TABLE: pincodes
-- ============================================
CREATE TABLE IF NOT EXISTS pincodes (
    id SERIAL PRIMARY KEY,
    pincode VARCHAR(6) NOT NULL,
    office_name VARCHAR(255),
    office_type VARCHAR(50),
    district VARCHAR(100),
    division VARCHAR(100),
    region VARCHAR(100),
    state VARCHAR(100),
    block VARCHAR(100),
    latitude DECIMAL(10, 8),
    longitude DECIMAL(11, 8),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_pincode ON pincodes(pincode);

-- ============================================
-- TABLE: pan_data
-- ============================================
CREATE TABLE IF NOT EXISTS pan_data (
    pan_number VARCHAR(10) PRIMARY KEY,
    full_name VARCHAR(255),
    father_name VARCHAR(255),
    date_of_birth DATE,
    gender VARCHAR(10),
    category VARCHAR(50),
    status VARCHAR(50),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_pan_number ON pan_data(pan_number);

-- ============================================
-- TABLE: subscriptions
-- ============================================
CREATE TABLE IF NOT EXISTS subscriptions (
    id SERIAL PRIMARY KEY,
    user_id INTEGER REFERENCES users(id),
    razorpay_subscription_id VARCHAR(100),
    razorpay_payment_id VARCHAR(100),
    razorpay_plan_id VARCHAR(100),
    plan_name VARCHAR(50),
    amount DECIMAL(10, 2),
    currency VARCHAR(3) DEFAULT 'INR',
    status VARCHAR(50),
    current_period_start TIMESTAMP,
    current_period_end TIMESTAMP,
    created_at TIMESTAMP DEFAULT NOW(),
    cancelled_at TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_subscriptions_user ON subscriptions(user_id);

-- ============================================
-- TABLE: invoices
-- ============================================
CREATE TABLE IF NOT EXISTS invoices (
    id SERIAL PRIMARY KEY,
    user_id INTEGER REFERENCES users(id),
    subscription_id INTEGER REFERENCES subscriptions(id),
    invoice_number VARCHAR(50) UNIQUE,
    amount DECIMAL(10, 2),
    tax_amount DECIMAL(10, 2),
    total_amount DECIMAL(10, 2),
    currency VARCHAR(3) DEFAULT 'INR',
    status VARCHAR(50),
    razorpay_invoice_id VARCHAR(100),
    razorpay_payment_id VARCHAR(100),
    invoice_date DATE,
    due_date DATE,
    paid_at TIMESTAMP,
    pdf_url VARCHAR(500),
    created_at TIMESTAMP DEFAULT NOW()
);
`;

/**
 * Run database setup
 */
const setupDatabase = async () => {
  console.log('🚀 Starting database setup...\n');

  const client = await pool.connect();

  try {
    // Start transaction
    await client.query('BEGIN');

    // Create tables
    console.log('📦 Creating tables...');
    await client.query(createTablesSQL);
    console.log('✅ Tables created successfully\n');

    // Commit transaction
    await client.query('COMMIT');

    // Display created tables
    const tablesResult = await client.query(`
      SELECT table_name 
      FROM information_schema.tables 
      WHERE table_schema = 'public' 
      AND table_type = 'BASE TABLE'
      ORDER BY table_name;
    `);

    console.log('📋 Created tables:');
    tablesResult.rows.forEach((row, index) => {
      console.log(`   ${index + 1}. ${row.table_name}`);
    });

    console.log('\n✅ Database setup completed successfully!');

  } catch (error) {
    // Rollback on error
    await client.query('ROLLBACK');
    console.error('\n❌ Database setup failed:', error.message);
    console.error('🔄 Transaction rolled back');
    throw error;
  } finally {
    client.release();
  }
};

// Run setup
setupDatabase()
  .then(() => {
    console.log('\n👋 Exiting...');
    process.exit(0);
  })
  .catch((error) => {
    console.error('\n💥 Fatal error:', error);
    process.exit(1);
  });
