import { adapters, newUuid, migrationFields } from '@/services/serviceConfig';
import { PERMISSION_PRESETS, resolvePermissions } from '@/config/permissions';
import { auditService } from '@/services/auditService';

const ENTITY = 'WorkshopAccount';

export const accountService = {
  list: () => adapters.database.list(ENTITY),
  listByRole: (role) => adapters.database.filter(ENTITY, { role }),
  getByUserId: (userId) => adapters.database.filter(ENTITY, { user_id: userId }).then(r => r[0] || null),
  get: (uuid) => adapters.database.filter(ENTITY, { uuid }).then(r => r[0] || null),
  getByEmail: (email) => adapters.database.filter(ENTITY, { email }).then(r => r[0] || null),

  create: (data, actor = 'Workshop Owner') => {
    const rec = {
      uuid: newUuid('account'),
      account_status: data.account_status || 'Invited',
      permission_keys: resolvePermissions({ role: data.role, permission_preset: data.permission_preset, custom_permissions: data.custom_permissions }),
      ...migrationFields(actor),
      ...data,
    };
    return adapters.database.create(ENTITY, rec).then(r => {
      auditService.record('account_created', ENTITY, rec.uuid, `Created ${data.role} account for ${data.email}`, actor);
      return r;
    });
  },

  update: (account, patch, actor = 'Workshop Owner') => {
    const next = { ...patch, updated_by_name: actor, revision: (account.revision || 1) + 1 };
    return adapters.database.update(ENTITY, account.id, next).then(r => {
      if (patch.role && patch.role !== account.role)
        auditService.record('role_changed', ENTITY, account.uuid, `${account.role} → ${patch.role}`, actor);
      if (patch.custom_permissions || patch.permission_preset)
        auditService.record('permissions_changed', ENTITY, account.uuid, 'Permission set updated', actor);
      return r;
    });
  },

  resolveForCurrentUser: async (user, actorName = 'Workshop Owner') => {
    if (!user) return null;
    let acc = await accountService.getByUserId(user.id);
    if (acc) {
      if (acc.account_status === 'Suspended' || acc.account_status === 'Archived') return acc;
      return acc;
    }
    // Bootstrap: first admin-role built-in user with no owner_admin yet becomes owner_admin.
    const owners = await adapters.database.filter(ENTITY, { role: 'owner_admin' }, '-created_date', 10);
    const role = user.role === 'admin' && owners.length === 0 ? 'owner_admin'
      : user.role === 'admin' ? 'admin' : 'customer';
    acc = await accountService.create({
      uuid: newUuid('account'), user_id: user.id, email: user.email,
      display_name: user.full_name || user.email, role,
      permission_preset: role === 'owner_admin' ? 'owner_admin' : role === 'admin' ? 'workshop_admin' : 'customer',
      account_status: 'Active', email_verified: true,
      last_login: new Date().toISOString(),
    }, actorName);
    return acc;
  },

  suspend: (account, reason, actor = 'Workshop Owner') =>
    accountService.update(account, { account_status: 'Suspended', suspended_date: new Date().toISOString(), suspended_by: actor, suspension_reason: reason }, actor)
      .then(r => { auditService.record('account_suspended', ENTITY, account.uuid, reason, actor); return r; }),

  reactivate: (account, actor = 'Workshop Owner') =>
    accountService.update(account, { account_status: 'Active', suspended_date: null, suspended_by: null, suspension_reason: null }, actor)
      .then(r => { auditService.record('account_reactivated', ENTITY, account.uuid, 'Account reactivated', actor); return r; }),

  revokeSessions: (account, actor = 'Workshop Owner') =>
    accountService.update(account, { session_revocation_date: new Date().toISOString() }, actor)
      .then(r => { auditService.record('sessions_revoked', ENTITY, account.uuid, 'Sessions revoked', actor); return r; }),

  archive: (account, actor = 'Workshop Owner') =>
    accountService.update(account, { account_status: 'Archived', archived_date: new Date().toISOString() }, actor)
      .then(r => { auditService.record('account_archived', ENTITY, account.uuid, 'Account archived', actor); return r; }),

  assignProject: (account, projectUuid, actor = 'Workshop Owner') => {
    const set = new Set(account.assigned_project_uuids || []);
    set.add(projectUuid);
    return accountService.update(account, { assigned_project_uuids: [...set] }, actor)
      .then(r => { auditService.record('project_assigned', ENTITY, account.uuid, `Assigned project ${projectUuid}`, actor); return r; });
  },

  unassignProject: (account, projectUuid, actor = 'Workshop Owner') => {
    const set = new Set(account.assigned_project_uuids || []);
    set.delete(projectUuid);
    return accountService.update(account, { assigned_project_uuids: [...set] }, actor)
      .then(r => { auditService.record('project_unassigned', ENTITY, account.uuid, `Unassigned project ${projectUuid}`, actor); return r; });
  },

  canAccessProject: (account, projectUuid) => {
    if (!account) return false;
    if (account.role === 'owner_admin' || account.role === 'admin') return true;
    if (account.role === 'customer') return false; // customers use portal, filtered by customer_uuid
    return (account.assigned_project_uuids || []).includes(projectUuid);
  },
};