/**
 * Database Migration: Create all tables
 * This migration creates all the necessary tables for the overseas appointment system
 */

module.exports = {
  up: async (queryInterface, Sequelize) => {
    // Create user table
    await queryInterface.createTable('user', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      wechat_open_id: {
        type: Sequelize.STRING(100),
        allowNull: false,
        unique: true,
      },
      wechat_union_id: {
        type: Sequelize.STRING(100),
        allowNull: true,
      },
      nickname: {
        type: Sequelize.STRING(100),
        allowNull: true,
      },
      avatar: {
        type: Sequelize.STRING(500),
        allowNull: true,
      },
      real_name: {
        type: Sequelize.STRING(100),
        allowNull: true,
      },
      phone: {
        type: Sequelize.STRING(20),
        allowNull: true,
      },
      whatsapp: {
        type: Sequelize.STRING(20),
        allowNull: true,
      },
      wechat_id: {
        type: Sequelize.STRING(100),
        allowNull: true,
      },
      language: {
        type: Sequelize.ENUM('zh', 'en', 'pt'),
        defaultValue: 'zh',
        allowNull: false,
      },
      balance: {
        type: Sequelize.DECIMAL(10, 2),
        defaultValue: 0.00,
        allowNull: false,
      },
      invitation_code: {
        type: Sequelize.STRING(20),
        allowNull: true,
        unique: true,
      },
      invited_by: {
        type: Sequelize.UUID,
        allowNull: true,
      },
      status: {
        type: Sequelize.ENUM('active', 'suspended'),
        defaultValue: 'active',
        allowNull: false,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Create category table
    await queryInterface.createTable('category', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      key: {
        type: Sequelize.STRING(50),
        allowNull: false,
        unique: true,
      },
      name_zh: {
        type: Sequelize.STRING(100),
        allowNull: false,
      },
      name_en: {
        type: Sequelize.STRING(100),
        allowNull: false,
      },
      name_pt: {
        type: Sequelize.STRING(100),
        allowNull: false,
      },
      icon: {
        type: Sequelize.STRING(500),
        allowNull: true,
      },
      sort_order: {
        type: Sequelize.INTEGER,
        defaultValue: 0,
        allowNull: false,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Create service table
    await queryInterface.createTable('service', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      category_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'category',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'RESTRICT',
      },
      title_zh: {
        type: Sequelize.STRING(200),
        allowNull: false,
      },
      title_en: {
        type: Sequelize.STRING(200),
        allowNull: false,
      },
      title_pt: {
        type: Sequelize.STRING(200),
        allowNull: false,
      },
      description_zh: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      description_en: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      description_pt: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      image: {
        type: Sequelize.STRING(500),
        allowNull: true,
      },
      price: {
        type: Sequelize.DECIMAL(10, 2),
        allowNull: true,
      },
      status: {
        type: Sequelize.ENUM('active', 'inactive'),
        defaultValue: 'active',
        allowNull: false,
      },
      sort_order: {
        type: Sequelize.INTEGER,
        defaultValue: 0,
        allowNull: false,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Create admin table
    await queryInterface.createTable('admin', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      username: {
        type: Sequelize.STRING(50),
        allowNull: false,
        unique: true,
      },
      password: {
        type: Sequelize.STRING(255),
        allowNull: false,
      },
      email: {
        type: Sequelize.STRING(100),
        allowNull: true,
      },
      role: {
        type: Sequelize.ENUM('super_admin', 'admin', 'operator'),
        defaultValue: 'operator',
        allowNull: false,
      },
      status: {
        type: Sequelize.ENUM('active', 'inactive'),
        defaultValue: 'active',
        allowNull: false,
      },
      last_login_at: {
        type: Sequelize.DATE,
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Create appointment table
    await queryInterface.createTable('appointment', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      user_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'user',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'RESTRICT',
      },
      service_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'service',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'RESTRICT',
      },
      appointment_no: {
        type: Sequelize.STRING(50),
        allowNull: false,
        unique: true,
      },
      real_name: {
        type: Sequelize.STRING(100),
        allowNull: false,
      },
      contact_method: {
        type: Sequelize.ENUM('phone', 'whatsapp', 'wechat'),
        allowNull: false,
      },
      contact_value: {
        type: Sequelize.STRING(100),
        allowNull: false,
      },
      appointment_date: {
        type: Sequelize.DATEONLY,
        allowNull: true,
      },
      appointment_time: {
        type: Sequelize.TIME,
        allowNull: true,
      },
      notes: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      status: {
        type: Sequelize.ENUM('pending', 'confirmed', 'in-progress', 'completed', 'cancelled'),
        defaultValue: 'pending',
        allowNull: false,
      },
      amount: {
        type: Sequelize.DECIMAL(10, 2),
        allowNull: true,
      },
      paid_at: {
        type: Sequelize.DATE,
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Create invitation table
    await queryInterface.createTable('invitation', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      inviter_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'user',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'RESTRICT',
      },
      invitee_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'user',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'RESTRICT',
      },
      invitation_code: {
        type: Sequelize.STRING(20),
        allowNull: false,
      },
      registered_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      first_payment_at: {
        type: Sequelize.DATE,
        allowNull: true,
      },
      first_payment_amount: {
        type: Sequelize.DECIMAL(10, 2),
        allowNull: true,
      },
      reward_amount: {
        type: Sequelize.DECIMAL(10, 2),
        allowNull: true,
      },
      reward_status: {
        type: Sequelize.ENUM('pending', 'credited', 'cancelled'),
        defaultValue: 'pending',
        allowNull: false,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Create withdrawal table
    await queryInterface.createTable('withdrawal', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      user_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'user',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'RESTRICT',
      },
      withdrawal_no: {
        type: Sequelize.STRING(50),
        allowNull: false,
        unique: true,
      },
      amount: {
        type: Sequelize.DECIMAL(10, 2),
        allowNull: false,
      },
      payment_method: {
        type: Sequelize.ENUM('wechat', 'alipay', 'bank'),
        allowNull: false,
      },
      payment_details: {
        type: Sequelize.JSON,
        allowNull: false,
      },
      status: {
        type: Sequelize.ENUM('waiting', 'processing', 'completed', 'rejected'),
        defaultValue: 'waiting',
        allowNull: false,
      },
      reviewed_by: {
        type: Sequelize.UUID,
        allowNull: true,
        references: {
          model: 'admin',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'SET NULL',
      },
      reviewed_at: {
        type: Sequelize.DATE,
        allowNull: true,
      },
      rejection_reason: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      completed_at: {
        type: Sequelize.DATE,
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Create login_history table
    await queryInterface.createTable('login_history', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      user_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'user',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      user_type: {
        type: Sequelize.ENUM('user', 'admin'),
        defaultValue: 'user',
        allowNull: false,
      },
      ip_address: {
        type: Sequelize.STRING(45),
        allowNull: true,
      },
      user_agent: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      device_info: {
        type: Sequelize.JSON,
        allowNull: true,
      },
      login_at: {
        type: Sequelize.DATE,
        defaultValue: Sequelize.NOW,
        allowNull: false,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Create notification table
    await queryInterface.createTable('notification', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      user_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'user',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      type: {
        type: Sequelize.ENUM('system', 'activity', 'service'),
        allowNull: false,
      },
      title_zh: {
        type: Sequelize.STRING(200),
        allowNull: false,
      },
      title_en: {
        type: Sequelize.STRING(200),
        allowNull: false,
      },
      title_pt: {
        type: Sequelize.STRING(200),
        allowNull: false,
      },
      content_zh: {
        type: Sequelize.TEXT,
        allowNull: false,
      },
      content_en: {
        type: Sequelize.TEXT,
        allowNull: false,
      },
      content_pt: {
        type: Sequelize.TEXT,
        allowNull: false,
      },
      is_read: {
        type: Sequelize.BOOLEAN,
        defaultValue: false,
        allowNull: false,
      },
      read_at: {
        type: Sequelize.DATE,
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes
    await queryInterface.addIndex('user', ['wechat_open_id']);
    await queryInterface.addIndex('user', ['invitation_code']);
    await queryInterface.addIndex('user', ['status']);
    
    await queryInterface.addIndex('category', ['key']);
    await queryInterface.addIndex('category', ['sort_order']);
    
    await queryInterface.addIndex('service', ['category_id']);
    await queryInterface.addIndex('service', ['status']);
    await queryInterface.addIndex('service', ['sort_order']);
    
    await queryInterface.addIndex('appointment', ['user_id']);
    await queryInterface.addIndex('appointment', ['service_id']);
    await queryInterface.addIndex('appointment', ['appointment_no']);
    await queryInterface.addIndex('appointment', ['status']);
    await queryInterface.addIndex('appointment', ['appointment_date']);
    
    await queryInterface.addIndex('invitation', ['inviter_id']);
    await queryInterface.addIndex('invitation', ['invitee_id']);
    await queryInterface.addIndex('invitation', ['invitation_code']);
    await queryInterface.addIndex('invitation', ['reward_status']);
    
    await queryInterface.addIndex('withdrawal', ['user_id']);
    await queryInterface.addIndex('withdrawal', ['withdrawal_no']);
    await queryInterface.addIndex('withdrawal', ['status']);
    await queryInterface.addIndex('withdrawal', ['reviewed_by']);
    
    await queryInterface.addIndex('notification', ['user_id']);
    await queryInterface.addIndex('notification', ['type']);
    await queryInterface.addIndex('notification', ['is_read']);
    
    await queryInterface.addIndex('admin', ['username']);
    await queryInterface.addIndex('admin', ['status']);
    await queryInterface.addIndex('admin', ['role']);
    
    await queryInterface.addIndex('login_history', ['user_id']);
    await queryInterface.addIndex('login_history', ['user_type']);
    await queryInterface.addIndex('login_history', ['login_at']);

    // Create config table
    await queryInterface.createTable('config', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      key: {
        type: Sequelize.STRING(100),
        allowNull: false,
        unique: true,
      },
      value: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      type: {
        type: Sequelize.ENUM('string', 'number', 'boolean', 'json', 'image'),
        defaultValue: 'string',
        allowNull: false,
      },
      category: {
        type: Sequelize.STRING(50),
        defaultValue: 'general',
        allowNull: false,
      },
      description: {
        type: Sequelize.STRING(500),
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
        defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
        defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
      },
    });

    await queryInterface.addIndex('config', ['key'], { unique: true });
    await queryInterface.addIndex('config', ['category']);
  },

  down: async (queryInterface) => {
    // Drop tables in reverse order to respect foreign key constraints
    await queryInterface.dropTable('config');
    await queryInterface.dropTable('notification');
    await queryInterface.dropTable('login_history');
    await queryInterface.dropTable('withdrawal');
    await queryInterface.dropTable('invitation');
    await queryInterface.dropTable('appointment');
    await queryInterface.dropTable('admin');
    await queryInterface.dropTable('service');
    await queryInterface.dropTable('category');
    await queryInterface.dropTable('user');
  },
};
