import { Page } from '@playwright/test';

export class AuthHelper {
  constructor(private page: Page) {}

  async login(email: string = 'admin@px360.sa', password: string = 'admin123') {
    await this.page.goto('/accounts/login/');
    await this.page.waitForSelector('#email');
    await this.page.fill('#email', email);
    await this.page.fill('#password', password);
    await this.page.click('button[type="submit"]');
  }

  async logout() {
    await this.page.goto('/accounts/logout/');
    await this.page.waitForURL(/\/accounts\/login\/?/, { timeout: 10000 });
  }
}

export class PublicFormHelper {
  constructor(private page: Page) {}

  async goToPublicLanding() {
    await this.page.goto('/core/public/submit/');
    await this.page.waitForSelector('.selection-card');
  }

  async selectFormType(type: 'complaint' | 'observation' | 'inquiry') {
    await this.page.click(`.selection-card[data-type="${type}"]`);
    await this.page.waitForSelector('#publicFormContainer.active', { timeout: 10000 });
  }

  async fillComplaintForm(data: {
    complainantName: string;
    relationToPatient: string;
    mobileNumber: string;
    patientName: string;
    nationalId: string;
    incidentDate: string;
    complaintDetails: string;
    email?: string;
  }) {
    await this.page.fill('#id_complainant_name', data.complainantName);
    await this.page.selectOption('#id_relation_to_patient', data.relationToPatient);
    if (data.email) await this.page.fill('#id_email', data.email);
    await this.page.fill('#id_mobile_number', data.mobileNumber);
    await this.page.fill('#id_patient_name', data.patientName);
    await this.page.fill('#id_national_id', data.nationalId);
    await this.page.fill('#id_incident_date', data.incidentDate);
    await this.page.fill('#id_complaint_details', data.complaintDetails);
  }

  async submitComplaint() {
    await this.page.click('#submit_btn');
  }

  async fillInquiryForm(data: {
    name: string;
    email: string;
    phone: string;
    hospital: string;
    category: string;
    subject: string;
    message: string;
  }) {
    await this.page.fill('#inquiry_name', data.name);
    await this.page.fill('#inquiry_email', data.email);
    await this.page.fill('#inquiry_phone', data.phone);
    await this.page.selectOption('#inquiry_hospital', data.hospital);
    await this.page.selectOption('#inquiry_category', data.category);
    await this.page.fill('#inquiry_subject', data.subject);
    await this.page.fill('#inquiry_message', data.message);
  }

  async submitInquiry() {
    await this.page.click('#inquirySubmitBtn');
  }

  async fillObservationForm(data: {
    description: string;
    title?: string;
    locationText?: string;
    reporterName?: string;
    reporterPhone?: string;
    reporterEmail?: string;
  }) {
    if (data.title) await this.page.fill('input[name="title"]', data.title);
    await this.page.fill('textarea[name="description"]', data.description);
    if (data.locationText) await this.page.fill('input[name="location_text"]', data.locationText);
    if (data.reporterName) await this.page.fill('input[name="reporter_name"]', data.reporterName);
    if (data.reporterPhone) await this.page.fill('input[name="reporter_phone"]', data.reporterPhone);
    if (data.reporterEmail) await this.page.fill('input[name="reporter_email"]', data.reporterEmail);
  }

  async submitObservation() {
    await this.page.click('button[type="submit"]');
  }

  async trackComplaint(referenceNumber: string) {
    await this.page.goto('/complaints/public/track/');
    await this.page.fill('input[name="reference_number"]', referenceNumber);
    await this.page.click('button[type="submit"]');
  }

  async trackObservation(trackingCode: string) {
    await this.page.goto('/observations/track/');
    await this.page.fill('input[name="tracking_code"]', trackingCode);
    await this.page.click('button[type="submit"]');
  }
}

export class DashboardHelper {
  constructor(private page: Page) {}

  async goToDashboard() {
    await this.page.goto('/');
    await this.page.waitForLoadState('networkidle');
  }

  async goToCommandCenter() {
    await this.page.goto('/');
    await this.page.waitForLoadState('networkidle');
  }
}

export type RoleName =
  | 'px_admin'
  | 'hospital_admin'
  | 'dept_manager'
  | 'px_employee'
  | 'physician'
  | 'nurse'
  | 'staff'
  | 'viewer'
  | 'source_user'
  | 'champion';

interface RoleConfig {
  email: string;
  password: string;
  groupName: string;
  hasHospital: boolean;
  canAccessConfig: boolean;
  canAccessAdmin: boolean;
  isSourceUser: boolean;
}

const E2E_PASSWORD = process.env.E2E_PASSWORD || 'Dev@123456';

export const ROLES: Record<RoleName, RoleConfig> = {
  px_admin: {
    email: 'e2e-px-admin@px360.test',
    password: E2E_PASSWORD,
    groupName: 'PX Admin',
    hasHospital: false,
    canAccessConfig: true,
    canAccessAdmin: false,
    isSourceUser: false,
  },
  hospital_admin: {
    email: 'e2e-hospital-admin@px360.test',
    password: E2E_PASSWORD,
    groupName: 'Hospital Admin',
    hasHospital: true,
    canAccessConfig: false,
    canAccessAdmin: false,
    isSourceUser: false,
  },
  dept_manager: {
    email: 'e2e-dept-manager@px360.test',
    password: E2E_PASSWORD,
    groupName: 'Department Manager',
    hasHospital: true,
    canAccessConfig: false,
    canAccessAdmin: false,
    isSourceUser: false,
  },
  px_employee: {
    email: 'e2e-px-employee@px360.test',
    password: E2E_PASSWORD,
    groupName: 'PX Employee',
    hasHospital: true,
    canAccessConfig: false,
    canAccessAdmin: false,
    isSourceUser: false,
  },
  physician: {
    email: 'e2e-physician@px360.test',
    password: E2E_PASSWORD,
    groupName: 'Physician',
    hasHospital: true,
    canAccessConfig: false,
    canAccessAdmin: false,
    isSourceUser: false,
  },
  nurse: {
    email: 'e2e-nurse@px360.test',
    password: E2E_PASSWORD,
    groupName: 'Nurse',
    hasHospital: true,
    canAccessConfig: false,
    canAccessAdmin: false,
    isSourceUser: false,
  },
  staff: {
    email: 'e2e-staff@px360.test',
    password: E2E_PASSWORD,
    groupName: 'Staff',
    hasHospital: true,
    canAccessConfig: false,
    canAccessAdmin: false,
    isSourceUser: false,
  },
  viewer: {
    email: 'e2e-viewer@px360.test',
    password: E2E_PASSWORD,
    groupName: 'Viewer',
    hasHospital: true,
    canAccessConfig: false,
    canAccessAdmin: false,
    isSourceUser: false,
  },
  source_user: {
    email: 'e2e-source-user@px360.test',
    password: E2E_PASSWORD,
    groupName: 'PX Source User',
    hasHospital: true,
    canAccessConfig: false,
    canAccessAdmin: false,
    isSourceUser: true,
  },
  champion: {
    email: 'e2e-champion@px360.test',
    password: E2E_PASSWORD,
    groupName: 'Department Manager',
    hasHospital: true,
    canAccessConfig: false,
    canAccessAdmin: false,
    isSourceUser: false,
  },
};

export class RoleAuthHelper {
  constructor(private page: Page) {}

  async login(role: RoleName) {
    const config = ROLES[role];
    await this.page.goto('/accounts/login/');
    await this.page.waitForSelector('#email');
    await this.page.fill('#email', config.email);
    await this.page.fill('#password', config.password);
    await this.page.click('button[type="submit"]');
    await this.page.waitForURL(/\/(?!accounts\/login)/, { timeout: 15000 });
    await this.page.waitForLoadState('domcontentloaded');
  }

  async loginAs(role: RoleName) {
    return this.login(role);
  }

  async logout() {
    await this.page.goto('/accounts/logout/');
    await this.page.waitForURL(/\/accounts\/login\/?/, { timeout: 10000 });
  }

  static config(role: RoleName): RoleConfig {
    return ROLES[role];
  }
}

export async function submitContentForm(page: Page) {
  await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
  await page.waitForTimeout(800);
  const formSelector = 'form:not([action*="logout"]):not([action*="login"])';
  const formEl = page.locator(formSelector).first();
  const count = await formEl.count();
  if (count === 0) {
    const fallback = page.locator('form').last();
    await fallback.evaluate((f: HTMLFormElement) => f.submit());
  } else {
    await formEl.evaluate((f: HTMLFormElement) => f.submit());
  }
  await page.waitForLoadState('domcontentloaded');
  await page.waitForTimeout(3000);
}
