import { Locator, Page } from "@playwright/test";
import { DashboardPage } from "../dashboard.page";
import { businessCreateNewContactModal, createNewContactBodyInDetailBusiness, createNewContactFooterInDetailBusiness, createNewContactHeaderInDetailBusiness, haveBusiness } from "./business.snapshot";

type APIBusinessData = {
  id: string;
  logo: string;
  name: string;
  type: { id: number; name: string };
  phone_number: string;
  fax_number: string;
  email_address: string;
  website_address: string;
  full_address: string;
  address_1: string;
  address_2: string;
  city: string;
  state_code: string;
  zip_code: string;
  tags: string[];
  is_verified: boolean;
  is_current_business: boolean;
  created_at: string;
  updated_at: string;
  groups: { id: number; name: string; total: number }[];
  notes: any[];
}

type ConvertedBusiness = {
  name: string;
  email_address: string;
  phone_number: string;
  website_address: string;
  full_address: string;
}

export class BusinessPage extends DashboardPage {
  constructor(page: Page) {
    super(page);
  }

  async open() {
    await this.page.goto("businesses");
  }

  get businessSnapshot() {
    return {
      haveBusiness: haveBusiness,
      createNewContactHeaderInDetailBusiness: createNewContactHeaderInDetailBusiness,
      createNewContactBodyInDetailBusiness: createNewContactBodyInDetailBusiness,
      createNewContactFooterInDetailBusiness: createNewContactFooterInDetailBusiness,
      businessCreateNewContactModal: businessCreateNewContactModal
    };
  }

  inputCreateBusiness = [
    {
      name: "name",
      id: "autocomplete_name",
      maxExceed: 100,
      child: 0
    },
    {
      name: "address",
      id: "input_address_1",
      maxExceed: 100,
      child: 0
    },
    {
      name: "suite, unit, etc",
      id: "input_address_2",
      maxExceed: 100,
      child: 0
    },
    {
      name: "city",
      id: "input_city",
      maxExceed: 50,
      child: 0
    },
    {
      name: "zip code",
      id: "input_zip_code",
      maxExceed: 50,
      child: 1
    }
  ]

  get businessProps() {
    return {
      filterProperties: [
        {
          name: 'business_contact_name',
          type: 'input',
          paramFilter: 'name'
        },
        {
          name: 'created',
          type: 'input',
          paramFilter: 'created_at'
        },
        {
          name: 'updated',
          type: 'input',
          paramFilter: 'updated_at'
        },
        {
          name: 'zip_code',
          type: 'input',
          paramFilter: 'zip_code'
        },
        {
          name: 'business_type_id',
          type: 'input',
          paramFilter: 'business_type_id'
        }
      ],
      threeDotDropdownMenus: {
        customizedColumn: 'Customized Columns',
      },
      customizedColumns: [
        {
          name: 'Pin',
          default: true,
          tableDisplayName: 'Pin'
        },
        {
          name: 'Type',
          default: true,
          tableDisplayName: 'Type'
        },
        {
          name: 'Business Name',
          default: true,
          tableDisplayName: 'Business Name'
        },
        {
          name: 'Phone',
          default: true,
          tableDisplayName: 'Phone'
        },
        {
          name: 'Email',
          default: true,
          tableDisplayName: 'Email'
        },
        {
          name: 'Address',
          default: true,
          tableDisplayName: 'Address'
        },
        {
          name: 'Fax Number',
          default: false,
          tableDisplayName: 'Fax Number'
        },
        {
          name: 'Website Address',
          default: false,
          tableDisplayName: 'Website Address'
        },
        {
          name: 'Created',
          default: false,
          tableDisplayName: 'Created'
        },
        {
          name: 'Updated',
          default: false,
          tableDisplayName: 'Updated'
        }
      ]
    }
  }

  get businessLoc() {
    return {
      btnNewBusiness: this.genLoc(
        `//div[@id='root']//button[contains(text(), 'New Business')]`
      ),
      btnFilter: this.genLoc(
        `//div[@id='root']//button[contains(text(), 'Filter')]`
      ),

      inputShow: this.genLoc(
        `//input[@class='form-control show-record-number ']`
      ),
      inputSearch: this.genLoc(
        `//input[@class='form-control' and @placeholder='Search...']`
      ),
      pinIcon: (businessName: string) => this.genLoc(`//a[normalize-space()='${businessName}']//ancestor::tr//a[@data-tooltip-content='Click here to pin!']`),
      pinnedIcon: (businessName: string) => this.genLoc(`//a[normalize-space()='${businessName}']//ancestor::tr//a[@data-tooltip-content='Click here to unpin!']`),
      firstBusiness: (businessId: string) => this.genLoc(`//div[contains(@class, 'card pin-card')]//a[@href='/businesses/${businessId}']`),

      //Detail Business
      nameDetailExist: (name: string) => this.genLoc(`//span[text()='${name}']`),
      nameDetail: this.genLoc("//span[contains(@class,'business-contact-name info-name')]"),
      emailDetail: this.genLoc("//div[@class='list-info-items'][1]/span[1]"),
      phoneDetail: this.genLoc("//div[@class='list-info-items'][1]/span[3]"),
      websiteDetail: this.genLoc("//div[@class='list-info-items'][2]/span[1]"),
      addressDetail: this.genLoc("//div[@class='list-info-items'][2]/span[3]"),

      //Create
      create: {
        checkboxCreateAnother: this.genLoc("//input[@name='create_contact']"),
        tag: (tagName: string) => this.genLoc(`//div[@class='box-selected']/descendant::span[text()='${tagName}']`),
        inputBusinessName: this.genLoc("(//input[@id='autocomplete_name'])[2]"),
        optionDropdown: (value: string) => this.genLoc(`//div[contains(@class,'title-option') and text()='${value}']`)
      },

      //Update modal
      btnClearTag: this.genLoc("//div[@class='box-selected']/span"),
      modalFormHeader: this.genLoc("//div/h3[text()='Business Detail']"),
      inputName: this.genLoc("(//div[@class='bg-disable form-control btn-open-suggest cursor-pointer form-input-wrapper'])[2] | //input[@name='name']"),
      inputEmail: this.genLoc("//input[@name='email_address']"),
      inputPhone: this.genLoc("//input[@name='phone_number']"),
      inputWebsite: this.genLoc("//input[@name='website_address']"),
      inputAddress: this.genLoc("((//div[@class='form-control btn-open-suggest cursor-pointer form-input-wrapper bg-disable'])[1] | //input[@name='address_1'])[1]"),
      inputSuite: this.genLoc("((//div[@class='form-control btn-open-suggest cursor-pointer form-input-wrapper bg-disable'])[2] | //input[@name='address_2'])[1]"),
      inputCity: this.genLoc("((//div[@class='form-control btn-open-suggest cursor-pointer form-input-wrapper bg-disable'])[3] | //input[@name='city'])[1]"),
      inputZip: this.genLoc("((//div[@class='form-control btn-open-suggest cursor-pointer form-input-wrapper bg-disable'])[4] | //input[@name='zip_code'])[1]"),
      inputState: this.genLoc("((//div[@class='bg-disable form-control btn-open-suggest cursor-pointer form-input-wrapper'])[3] | //input[@name='state_code'])[1]"),
      modalSuggestion: this.genLoc("//div/h3[text()='Suggestion']"),
      msgErrorDuplicateBusiness: this.genLoc("//p[contains(text(),'Duplicate entry matching your input')]"),

      //Three-dots button
      threeDotsBtn: this.genLoc("//div[@class='dropdown d-flex align-items-center']"),
      listActionDropdown: (action: string) => this.genLoc(`//span[text()='${action}']`),

      //Filter
      optionBusinessType: (option: string) => this.genLoc(`//div[@class='title-option' and text()='${option}']`),
      msgSuccess: this.genLoc("//p[text()='Updated Successfully!']"),

      detail: {
        dropdownOption:(action: string) => this.genLoc(`//span[@class='dropdown-item cursor-pointer' and text()='${action}']`),
        threeDotsBtn: this.genLoc("//div[@class='dropdown d-flex align-items-center']"),
      }
    };
  }
  
  async searchBusiness(search: string) {
    const inputSearchSelector = `//input[@class='form-control' and @placeholder='Search...']`;
    await this.page.locator(inputSearchSelector).click();
    await this.page.locator(inputSearchSelector).fill(search);
    await this.page.waitForTimeout(1000);
  }

  async getVisibleRowTexts(): Promise<string[]> {
    const tableRows = this.page.locator("table tbody tr");
    const count = await tableRows.count();
    const texts: string[] = [];

    for (let i = 0; i < count; i++) {
      const rowText = await tableRows.nth(i).textContent();
      if (rowText) texts.push(rowText.trim());
    }

    return texts;
  }

  async fetchDetailBusiness(): Promise<ConvertedBusiness> {
    const apiData = await this.getInfoDetail<APIBusinessData>("businesses");

    return {
      name: apiData.name || "--",
      email_address: apiData.email_address || "--",
      phone_number: apiData.phone_number || "--",
      website_address: apiData.website_address || "--",
      full_address: apiData.full_address || "--",
    }
  }

  async getBusinessDetailUI(): Promise<ConvertedBusiness> {
    const name = (await this.businessLoc.nameDetail.textContent() || "").trim();
    const rawEmail = (await this.businessLoc.emailDetail.textContent() || "").trim();
    const rawPhone = (await this.businessLoc.phoneDetail.textContent() || "").trim();
    const rawWebsite = (await this.businessLoc.websiteDetail.textContent() || "").trim();
    const rawAddress = (await this.businessLoc.addressDetail.textContent() || "").trim();

    // Delete unnecessary values
    const email = rawEmail.replace(/Email Address:\s*/, '').trim();
    const website = rawWebsite.replace(/^Website Address:\s*/, "").trim();
    const phone = rawPhone.replace(/Phone Number:\s*/, '').trim();
    const address = rawAddress.replace(/Address:\s*/, '').trim();

    return { name: name, email_address: email, phone_number: phone, website_address: website, full_address: address || '--' };
  }

  async getBusinessModalUpdateUI(): Promise<ConvertedBusiness> {
    const name = (await this.businessLoc.inputName.textContent() || await this.businessLoc.inputName.inputValue()) || '--';
    const email = await this.businessLoc.inputEmail.first().inputValue() || '--';
    const phone = await this.businessLoc.inputPhone.first().inputValue() || '--';
    const website = await this.businessLoc.inputWebsite.inputValue() || '--';
    const [
      address,
      suite,
      city,
      state,
      zip
    ] = await Promise.all([
      this.getElementValue(this.businessLoc.inputAddress),
      this.getElementValue(this.businessLoc.inputSuite),
      this.getElementValue(this.businessLoc.inputCity),
      this.getElementValue(this.businessLoc.inputState),
      this.getElementValue(this.businessLoc.inputZip),
    ]).then(values =>
      values.map(v => (v || "").trim())
    );

    const fullAdress = [
      address,
      suite,
      `${city}${state ? `, ${state}` : ""} ${zip}`.trim()
    ]
      .filter(part => part.length > 0)
      .join(", ");

    return { name: name, email_address: email, phone_number: phone.replace(/\(\s*(\d{3})\s*\)\s*(\d{3})-(\d{4})/,"($1) $2 - $3"), website_address: website, full_address: fullAdress || "--" }
  }

  async getElementValue(locator: Locator) {
    const tagName = await locator.evaluate(el => el.tagName.toLowerCase());

    if (tagName === 'input') {
      return (await locator.inputValue()) || '';
    }

    return (await locator.innerText()) || '';
  }
}
