const { v4: uuid } = require("uuid");

module.exports = {
  /**
   * @param{import("sequelize").QueryInterface} queryInterface
   * @return {Promise<void>}
   */
  async up(queryInterface) {
    const createdAt = new Date();
    const updatedAt = new Date();

    /** @type {Map<string, string>} */
    const idMap = new Map();

    /**
     * @param {string} key
     * @return {string}
     */
    function getId(key) {
      if (idMap.has(key)) {
        return idMap.get(key);
      }
      const id = uuid();
      idMap.set(key, id);
      return id;
    }

    await queryInterface.bulkInsert("roles", [
      { id: getId("Administrator"), name: "Administrator", createdAt, updatedAt },
      { id: getId("PlatformOwner"), name: "Platform Owner", createdAt, updatedAt },
      { id: getId("Trust&SafetyLead"), name: "Trust & Safety Lead", createdAt, updatedAt },
      { id: getId("MarketplaceOpsManager"), name: "Marketplace Ops Manager", createdAt, updatedAt },
      { id: getId("BusinessSupportAgent"), name: "Business Support Agent", createdAt, updatedAt },
      { id: getId("VerifiedBusinessOwner"), name: "Verified Business Owner", createdAt, updatedAt },
      { id: getId("Consumer"), name: "Consumer", createdAt, updatedAt },
      { id: getId("Public"), name: "Public", createdAt, updatedAt },
    ]);

    /**
     * @param {string} name
     */
    function createPermissions(name) {
      return [
        { id: getId(`CREATE_${name.toUpperCase()}`), createdAt, updatedAt, name: `CREATE_${name.toUpperCase()}` },
        { id: getId(`READ_${name.toUpperCase()}`), createdAt, updatedAt, name: `READ_${name.toUpperCase()}` },
        { id: getId(`UPDATE_${name.toUpperCase()}`), createdAt, updatedAt, name: `UPDATE_${name.toUpperCase()}` },
        { id: getId(`DELETE_${name.toUpperCase()}`), createdAt, updatedAt, name: `DELETE_${name.toUpperCase()}` }
      ];
    }

    const entities = [
      "users","roles","permissions","refresh_tokens","categories","locations","businesses","business_photos","business_categories","service_prices","business_badges","verification_submissions","verification_evidences","leads","lead_photos","lead_matches","messages","lead_events","reviews","disputes","audit_logs","badge_rules","trust_adjustments",
    ];
    await queryInterface.bulkInsert("permissions", entities.flatMap(createPermissions));
    await queryInterface.bulkInsert("permissions", [{ id: getId(`READ_API_DOCS`), createdAt, updatedAt, name: `READ_API_DOCS` }]);
    await queryInterface.bulkInsert("permissions", [{ id: getId(`CREATE_SEARCH`), createdAt, updatedAt, name: `CREATE_SEARCH`}]);


    await queryInterface.sequelize.query(`create table "rolesPermissionsPermissions"
    (
    "createdAt"           timestamp with time zone not null,
    "updatedAt"           timestamp with time zone not null,
    "roles_permissionsId" uuid                     not null,
    "permissionId"        uuid                     not null,
    primary key ("roles_permissionsId", "permissionId")
    );`);

    const rolePerms = [];

    // PUBLIC Permissions
    const publicPerms = ["READ_CATEGORIES", "READ_LOCATIONS", "READ_BUSINESSES", "READ_REVIEWS", "READ_BUSINESS_PHOTOS", "READ_SERVICE_PRICES", "READ_BUSINESS_BADGES"];
    publicPerms.forEach(p => rolePerms.push({ createdAt, updatedAt, roles_permissionsId: getId("Public"), permissionId: getId(p) }));

    // CONSUMER Permissions (Users)
    const consumerPerms = [
        ...publicPerms,
        "CREATE_REVIEWS", "UPDATE_REVIEWS", "DELETE_REVIEWS",
        "CREATE_LEADS", "READ_LEADS", "UPDATE_LEADS",
        "CREATE_LEAD_PHOTOS", "READ_LEAD_PHOTOS",
        "CREATE_MESSAGES", "READ_MESSAGES",
        "READ_LEAD_EVENTS", "CREATE_SEARCH"
    ];
    consumerPerms.forEach(p => rolePerms.push({ createdAt, updatedAt, roles_permissionsId: getId("Consumer"), permissionId: getId(p) }));

    // BUSINESS Permissions (Clients)
    const businessPerms = [
        ...publicPerms,
        "READ_REVIEWS", "UPDATE_REVIEWS", // Added UPDATE_REVIEWS for responding to reviews
        "READ_LEADS", "UPDATE_LEADS",
        "READ_LEAD_PHOTOS",
        "CREATE_MESSAGES", "READ_MESSAGES",
        "READ_LEAD_EVENTS",
        "CREATE_BUSINESS_PHOTOS", "UPDATE_BUSINESS_PHOTOS", "DELETE_BUSINESS_PHOTOS",
        "CREATE_SERVICE_PRICES", "UPDATE_SERVICE_PRICES", "DELETE_SERVICE_PRICES",
        "CREATE_VERIFICATION_SUBMISSIONS", "READ_VERIFICATION_SUBMISSIONS",
        "CREATE_VERIFICATION_EVIDENCES", "READ_VERIFICATION_EVIDENCES",
        "UPDATE_BUSINESSES", "CREATE_SEARCH"
    ];
    businessPerms.forEach(p => rolePerms.push({ createdAt, updatedAt, roles_permissionsId: getId("VerifiedBusinessOwner"), permissionId: getId(p) }));

    // ADMIN Permissions (Everything)
    const adminPerms = entities.flatMap(e => [`CREATE_${e.toUpperCase()}`, `READ_${e.toUpperCase()}`, `UPDATE_${e.toUpperCase()}`, `DELETE_${e.toUpperCase()}`]);
    adminPerms.push("READ_API_DOCS", "CREATE_SEARCH");
    adminPerms.forEach(p => {
        const id = getId(p);
        rolePerms.push({ createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: id });
        rolePerms.push({ createdAt, updatedAt, roles_permissionsId: getId("PlatformOwner"), permissionId: id });
    });

    await queryInterface.bulkInsert("rolesPermissionsPermissions", rolePerms);

    await queryInterface.sequelize.query(`UPDATE "users" SET "app_roleId"='${getId("Administrator")}' WHERE "email"='admin@flatlogic.com'`);
    await queryInterface.sequelize.query(`UPDATE "users" SET "app_roleId"='${getId("VerifiedBusinessOwner")}' WHERE "email"='client@hello.com'`);
    await queryInterface.sequelize.query(`UPDATE "users" SET "app_roleId"='${getId("Consumer")}' WHERE "email"='john@doe.com'`);
  }
};