/**
 * Unit Tests: Country Code Dropdown
 * Tests country code selector UI component
 */

import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";

describe("Country Code Dropdown", () => {
  // Mock country codes data (GCC countries)
  const countryCodes = [
    { code: "+974", country: "Qatar", flag: "🇶🇦" },
    { code: "+966", country: "Saudi Arabia", flag: "🇸🇦" },
    { code: "+971", country: "UAE", flag: "🇦🇪" },
    { code: "+965", country: "Kuwait", flag: "🇰🇼" },
    { code: "+973", country: "Bahrain", flag: "🇧🇭" },
    { code: "+968", country: "Oman", flag: "🇴🇲" },
  ];

  // Simple dropdown component for testing
  const CountryCodeDropdown = ({
    value,
    onChange,
    countryCodes,
  }: {
    value: string;
    onChange: (code: string) => void;
    countryCodes: Array<{ code: string; country: string; flag: string }>;
  }) => {
    return (
      <select
        data-testid="country-code-select"
        value={value}
        onChange={(e) => onChange(e.target.value)}
        aria-label="Country Code"
      >
        {countryCodes.map(({ code, country, flag }) => (
          <option key={code} value={code}>
            {flag} {code} {country}
          </option>
        ))}
        <option value="other">Other</option>
      </select>
    );
  };

  describe("Default Behavior", () => {
    it("should default to Qatar (+974)", () => {
      const onChange = jest.fn();
      render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const select = screen.getByTestId(
        "country-code-select",
      ) as HTMLSelectElement;
      expect(select.value).toBe("+974");
    });

    it("should display all GCC countries", () => {
      const onChange = jest.fn();
      const { container } = render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const options = container.querySelectorAll("option");
      // 6 GCC countries + 1 "Other" option
      expect(options).toHaveLength(7);
    });

    it('should include "Other" option', () => {
      const onChange = jest.fn();
      render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const otherOption = screen.getByText("Other");
      expect(otherOption).toBeInTheDocument();
    });
  });

  describe("Country Selection", () => {
    it("should call onChange when country selected", () => {
      const onChange = jest.fn();
      render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const select = screen.getByTestId("country-code-select");
      fireEvent.change(select, { target: { value: "+966" } });

      expect(onChange).toHaveBeenCalledWith("+966");
    });

    it("should update value when different country selected", () => {
      const onChange = jest.fn();
      const { rerender } = render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const select = screen.getByTestId(
        "country-code-select",
      ) as HTMLSelectElement;
      expect(select.value).toBe("+974");

      // Simulate selection change
      rerender(
        <CountryCodeDropdown
          value="+966"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      expect(select.value).toBe("+966");
    });

    it('should handle "Other" option selection', () => {
      const onChange = jest.fn();
      render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const select = screen.getByTestId("country-code-select");
      fireEvent.change(select, { target: { value: "other" } });

      expect(onChange).toHaveBeenCalledWith("other");
    });
  });

  describe("Phone Number Concatenation", () => {
    // Mock phone input component with country code
    const PhoneInput = ({
      countryCode,
      phoneNumber,
      onCountryCodeChange,
      onPhoneNumberChange,
    }: {
      countryCode: string;
      phoneNumber: string;
      onCountryCodeChange: (code: string) => void;
      onPhoneNumberChange: (phone: string) => void;
    }) => {
      const fullPhone =
        countryCode === "other" ? phoneNumber : `${countryCode}${phoneNumber}`;

      return (
        <div>
          <CountryCodeDropdown
            value={countryCode}
            onChange={onCountryCodeChange}
            countryCodes={countryCodes}
          />
          <input
            data-testid="phone-input"
            type="tel"
            value={phoneNumber}
            onChange={(e) => onPhoneNumberChange(e.target.value)}
            placeholder="Phone number"
          />
          <div data-testid="full-phone">{fullPhone}</div>
        </div>
      );
    };

    it("should concatenate country code with phone number", () => {
      const onCountryCodeChange = jest.fn();
      const onPhoneNumberChange = jest.fn();

      render(
        <PhoneInput
          countryCode="+974"
          phoneNumber="12345678"
          onCountryCodeChange={onCountryCodeChange}
          onPhoneNumberChange={onPhoneNumberChange}
        />,
      );

      const fullPhone = screen.getByTestId("full-phone");
      expect(fullPhone.textContent).toBe("+97412345678");
    });

    it("should update concatenation when country code changes", () => {
      const onCountryCodeChange = jest.fn();
      const onPhoneNumberChange = jest.fn();

      const { rerender } = render(
        <PhoneInput
          countryCode="+974"
          phoneNumber="12345678"
          onCountryCodeChange={onCountryCodeChange}
          onPhoneNumberChange={onPhoneNumberChange}
        />,
      );

      let fullPhone = screen.getByTestId("full-phone");
      expect(fullPhone.textContent).toBe("+97412345678");

      // Change country code
      rerender(
        <PhoneInput
          countryCode="+966"
          phoneNumber="12345678"
          onCountryCodeChange={onCountryCodeChange}
          onPhoneNumberChange={onPhoneNumberChange}
        />,
      );

      fullPhone = screen.getByTestId("full-phone");
      expect(fullPhone.textContent).toBe("+96612345678");
    });

    it('should not add prefix when "Other" selected', () => {
      const onCountryCodeChange = jest.fn();
      const onPhoneNumberChange = jest.fn();

      render(
        <PhoneInput
          countryCode="other"
          phoneNumber="+15551234567"
          onCountryCodeChange={onCountryCodeChange}
          onPhoneNumberChange={onPhoneNumberChange}
        />,
      );

      const fullPhone = screen.getByTestId("full-phone");
      expect(fullPhone.textContent).toBe("+15551234567");
    });

    it("should handle empty phone number", () => {
      const onCountryCodeChange = jest.fn();
      const onPhoneNumberChange = jest.fn();

      render(
        <PhoneInput
          countryCode="+974"
          phoneNumber=""
          onCountryCodeChange={onCountryCodeChange}
          onPhoneNumberChange={onPhoneNumberChange}
        />,
      );

      const fullPhone = screen.getByTestId("full-phone");
      expect(fullPhone.textContent).toBe("+974");
    });
  });

  describe("Accessibility", () => {
    it("should have accessible label", () => {
      const onChange = jest.fn();
      render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const select = screen.getByLabelText("Country Code");
      expect(select).toBeInTheDocument();
    });

    it("should be keyboard navigable", () => {
      const onChange = jest.fn();
      render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const select = screen.getByTestId("country-code-select");
      select.focus();
      expect(select).toHaveFocus();
    });
  });

  describe("Country Code Format", () => {
    it("should display country codes with + prefix", () => {
      const onChange = jest.fn();
      const { container } = render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const options = container.querySelectorAll("option");
      const codesWithPlus = Array.from(options)
        .filter((opt) => opt.value !== "other")
        .every((opt) => opt.value.startsWith("+"));

      expect(codesWithPlus).toBe(true);
    });

    it("should have unique country codes", () => {
      const onChange = jest.fn();
      const { container } = render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      const options = container.querySelectorAll("option");
      const codes = Array.from(options)
        .filter((opt) => opt.value !== "other")
        .map((opt) => opt.getAttribute("value"));

      const uniqueCodes = new Set(codes);
      expect(uniqueCodes.size).toBe(codes.length);
    });

    it("should include country flags in display", () => {
      const onChange = jest.fn();
      render(
        <CountryCodeDropdown
          value="+974"
          onChange={onChange}
          countryCodes={countryCodes}
        />,
      );

      // Check that Qatar flag is present
      const qatarOption = screen.getByText(/🇶🇦.*\+974.*Qatar/);
      expect(qatarOption).toBeInTheDocument();
    });
  });
});
