import { useState, useMemo, useEffect, useCallback } from 'react';
import type { Locale } from '../../data/site';
import { isoToEmojiFlag } from '../../lib/countries/flag';
import CVDetailDialog, { type CVDetail } from './CVDetailDialog';

type CV = CVDetail;

type ActiveFilter =
  | { type: 'country'; value: string; label: string }
  | { type: 'profession'; value: string; label: string }
  | { type: 'skill'; value: string; label: string }
  | { type: 'language'; value: string; label: string };

type Labels = {
  countryLabels: Record<string, { ar: string; en: string; isoCode: string }>;
  professionLabels: Record<string, { ar: string; en: string }>;
  viewCv: string;
  experience: string;
  age: string;
  salary: string;
  skills: string;
  languages: string;
  filterBy: string;
  nationality: string;
  profession: string;
  allNationalities: string;
  allProfessionsFilter: string;
  noResults: string;
  showFilters: string;
  hideFilters: string;
  clearFilters: string;
  results: string;
  yearsExp: string;
  yrs: string;
  perMonth: string;
  featured: string;
  video: string;
  bookViaWhatsApp: string;
  requestViaForm: string;
  musanedNote: string;
  maritalStatus: string;
  educationLevel: string;
  serviceType: string;
  close: string;
  basicInfo: string;
  religion: string;
  videoAvailable: string;
  years: string;
};

type Props = {
  locale: Locale;
  cvs: CV[];
  labels: Labels;
  initialProfession?: string;
  initialCountry?: string;
  initialCv?: string;
};

function updateCvParam(slug: string | null) {
  const url = new URL(window.location.href);
  if (slug) {
    url.searchParams.set('cv', slug);
  } else {
    url.searchParams.delete('cv');
  }
  window.history.replaceState({}, '', url);
}

function FilterIcon() {
  return (
    <svg className="h-5 w-5 text-secondary" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
      <path
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth={2}
        d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
      />
    </svg>
  );
}

function ChevronIcon({ open }: { open: boolean }) {
  return (
    <svg
      className={`h-5 w-5 text-primary-content/70 transition-transform duration-300 md:hidden ${open ? 'rotate-180' : ''}`}
      fill="none"
      stroke="currentColor"
      viewBox="0 0 24 24"
      aria-hidden="true"
    >
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
    </svg>
  );
}

function CloseIcon() {
  return (
    <svg className="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M6 18L18 6M6 6l12 12" />
    </svg>
  );
}

function TagFilterSection({
  title,
  items,
  selected,
  onToggle,
  defaultOpen,
  groupName,
}: {
  title: string;
  items: string[];
  selected: string[];
  onToggle: (value: string) => void;
  defaultOpen: boolean;
  groupName: string;
}) {
  if (items.length === 0) return null;

  return (
    <div className="collapse collapse-arrow border border-primary/20 rounded-lg bg-primary/5">
      <input type="checkbox" name={groupName} defaultChecked={defaultOpen} />
      <div className="collapse-title min-h-0 py-3 text-sm font-medium text-primary">{title}</div>
      <div className="collapse-content">
        <div className="flex flex-wrap gap-2 pb-3">
          {items.map((item) => (
            <button
              key={item}
              type="button"
              onClick={() => onToggle(item)}
              className={`btn btn-xs ${selected.includes(item) ? 'btn-primary' : 'btn-outline btn-primary'}`}
            >
              {item}
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}

export default function CVFilter({
  locale,
  cvs,
  labels,
  initialProfession = '',
  initialCountry = '',
  initialCv = '',
}: Props) {
  const [countryFilter, setCountryFilter] = useState(initialCountry);
  const [professionFilter, setProfessionFilter] = useState(initialProfession);
  const [skillsFilter, setSkillsFilter] = useState<string[]>([]);
  const [languagesFilter, setLanguagesFilter] = useState<string[]>([]);
  const [selectedCv, setSelectedCv] = useState<CV | null>(null);
  const [panelOpen, setPanelOpen] = useState(true);

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const country = params.get('country');
    const profession = params.get('profession');

    if (initialProfession) {
      setProfessionFilter(initialProfession);
    } else if (profession) {
      setProfessionFilter(profession);
    }

    if (country) {
      setCountryFilter(country);
    } else if (initialCountry) {
      setCountryFilter(initialCountry);
    }
  }, [initialProfession, initialCountry]);

  const openCv = useCallback((cv: CV) => {
    setSelectedCv(cv);
    updateCvParam(cv.slug);
  }, []);

  const closeCv = useCallback(() => {
    setSelectedCv(null);
    updateCvParam(null);
  }, []);

  useEffect(() => {
    const cvSlug = initialCv || new URLSearchParams(window.location.search).get('cv');
    if (!cvSlug) return;
    const cv = cvs.find((c) => c.slug === cvSlug);
    if (cv) setSelectedCv(cv);
  }, [initialCv, cvs]);

  const uniqueCountries = [...new Set(cvs.map((c) => c.country))];
  const uniqueProfessions = [...new Set(cvs.map((c) => c.profession))];
  const uniqueSkills = [...new Set(cvs.flatMap((c) => c.skills))].sort();
  const uniqueLanguages = [...new Set(cvs.flatMap((c) => c.languages))].sort();

  function toggle(list: string[], setList: (next: string[]) => void, value: string) {
    setList(list.includes(value) ? list.filter((item) => item !== value) : [...list, value]);
  }

  const activeFilters = useMemo(() => {
    const chips: ActiveFilter[] = [];

    if (countryFilter) {
      const countryInfo = labels.countryLabels[countryFilter];
      chips.push({
        type: 'country',
        value: countryFilter,
        label: `${isoToEmojiFlag(countryInfo?.isoCode ?? '')} ${countryInfo?.[locale] ?? countryFilter}`.trim(),
      });
    }

    if (professionFilter) {
      chips.push({
        type: 'profession',
        value: professionFilter,
        label: labels.professionLabels[professionFilter]?.[locale] ?? professionFilter,
      });
    }

    for (const skill of skillsFilter) {
      chips.push({ type: 'skill', value: skill, label: skill });
    }

    for (const language of languagesFilter) {
      chips.push({ type: 'language', value: language, label: language });
    }

    return chips;
  }, [countryFilter, professionFilter, skillsFilter, languagesFilter, labels, locale]);

  const activeCount = activeFilters.length;
  const hasActiveFilters = activeCount > 0;

  function clearAllFilters() {
    setCountryFilter('');
    setProfessionFilter('');
    setSkillsFilter([]);
    setLanguagesFilter([]);
  }

  function removeFilter(chip: ActiveFilter) {
    switch (chip.type) {
      case 'country':
        setCountryFilter('');
        break;
      case 'profession':
        setProfessionFilter('');
        break;
      case 'skill':
        setSkillsFilter((prev) => prev.filter((item) => item !== chip.value));
        break;
      case 'language':
        setLanguagesFilter((prev) => prev.filter((item) => item !== chip.value));
        break;
    }
  }

  const filtered = useMemo(() => {
    return cvs.filter((cv) => {
      if (countryFilter && cv.country !== countryFilter) return false;
      if (professionFilter && cv.profession !== professionFilter) return false;
      if (skillsFilter.length > 0 && !skillsFilter.every((skill) => cv.skills.includes(skill))) return false;
      if (languagesFilter.length > 0 && !languagesFilter.every((language) => cv.languages.includes(language)))
        return false;
      return true;
    });
  }, [cvs, countryFilter, professionFilter, skillsFilter, languagesFilter]);

  const dialogLabels = {
    nationality: labels.nationality,
    profession: labels.profession,
    age: labels.age,
    experience: labels.experience,
    salary: labels.salary,
    skills: labels.skills,
    languages: labels.languages,
    maritalStatus: labels.maritalStatus,
    educationLevel: labels.educationLevel,
    serviceType: labels.serviceType,
    bookViaWhatsApp: labels.bookViaWhatsApp,
    requestViaForm: labels.requestViaForm,
    musanedNote: labels.musanedNote,
    close: labels.close,
    basicInfo: labels.basicInfo,
    religion: labels.religion,
    videoAvailable: labels.videoAvailable,
    perMonth: labels.perMonth,
    years: labels.years,
  };

  const panelId = 'cv-filter-panel';

  return (
    <div>
      <section className="mb-8">
        <div className="overflow-hidden rounded-box border border-primary/20 bg-base-100 shadow-sm">
          <button
            type="button"
            className={`flex w-full items-center justify-between gap-3 px-4 py-3.5 text-start transition-colors md:cursor-default md:pointer-events-none ${
              hasActiveFilters ? 'border-s-4 border-s-secondary' : ''
            } bg-primary text-primary-content hover:bg-primary/90 md:hover:bg-primary`}
            onClick={() => setPanelOpen((open) => !open)}
            aria-expanded={panelOpen}
            aria-controls={panelId}
          >
            <div className="flex items-center gap-2.5">
              <FilterIcon />
              <span className="font-semibold">{labels.filterBy}</span>
              {hasActiveFilters && (
                <span className="badge badge-secondary badge-sm">{activeCount}</span>
              )}
            </div>
            <div className="flex items-center gap-2 md:hidden">
              <span className="text-xs text-primary-content/70">
                {panelOpen ? labels.hideFilters : labels.showFilters}
              </span>
              <ChevronIcon open={panelOpen} />
            </div>
          </button>

          <div
            id={panelId}
            className="filter-panel-body border-t border-primary/15 bg-primary/[0.03]"
            data-open={panelOpen ? 'true' : 'false'}
          >
            <div className="overflow-hidden">
              <div className="space-y-4 p-4">
                <div className="grid gap-4 sm:grid-cols-2">
                  <fieldset className="fieldset p-0">
                    <legend className="fieldset-legend text-sm font-medium text-primary">
                      {labels.nationality}
                    </legend>
                    <select
                      className="select select-bordered select-primary w-full"
                      value={countryFilter}
                      onChange={(e) => setCountryFilter(e.target.value)}
                      aria-label={labels.nationality}
                    >
                      <option value="">{labels.allNationalities}</option>
                      {uniqueCountries.map((c) => (
                        <option key={c} value={c}>
                          {isoToEmojiFlag(labels.countryLabels[c]?.isoCode ?? '')} {labels.countryLabels[c]?.[locale] ?? c}
                        </option>
                      ))}
                    </select>
                  </fieldset>

                  <fieldset className="fieldset p-0">
                    <legend className="fieldset-legend text-sm font-medium text-primary">
                      {labels.profession}
                    </legend>
                    <select
                      className="select select-bordered select-primary w-full"
                      value={professionFilter}
                      onChange={(e) => setProfessionFilter(e.target.value)}
                      aria-label={labels.profession}
                    >
                      <option value="">{labels.allProfessionsFilter}</option>
                      {uniqueProfessions.map((p) => (
                        <option key={p} value={p}>
                          {labels.professionLabels[p]?.[locale] ?? p}
                        </option>
                      ))}
                    </select>
                  </fieldset>
                </div>

                <TagFilterSection
                  title={labels.skills}
                  items={uniqueSkills}
                  selected={skillsFilter}
                  onToggle={(skill) => toggle(skillsFilter, setSkillsFilter, skill)}
                  defaultOpen={uniqueSkills.length <= 4}
                  groupName="cv-skills-filter"
                />

                <TagFilterSection
                  title={labels.languages}
                  items={uniqueLanguages}
                  selected={languagesFilter}
                  onToggle={(language) => toggle(languagesFilter, setLanguagesFilter, language)}
                  defaultOpen={uniqueLanguages.length <= 4}
                  groupName="cv-languages-filter"
                />

                {hasActiveFilters && (
                  <div className="flex justify-end pt-1">
                    <button
                      type="button"
                      onClick={clearAllFilters}
                      className="btn btn-ghost btn-sm text-primary"
                    >
                      {labels.clearFilters}
                    </button>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>

        {hasActiveFilters && (
          <div className="mt-3 flex flex-wrap gap-2">
            {activeFilters.map((chip) => (
              <span
                key={`${chip.type}-${chip.value}`}
                className="badge badge-outline badge-sm gap-1 border-primary/30 bg-primary/5 text-primary pe-1"
              >
                {chip.label}
                <button
                  type="button"
                  onClick={() => removeFilter(chip)}
                  className="inline-flex h-4 w-4 items-center justify-center rounded-full hover:bg-primary/15"
                  aria-label={`${labels.clearFilters}: ${chip.label}`}
                >
                  <CloseIcon />
                </button>
              </span>
            ))}
          </div>
        )}
      </section>

      <p className="text-sm text-base-content/60 mb-4">
        {filtered.length} {labels.results}
      </p>

      {filtered.length === 0 ? (
        <div className="text-center py-16 text-base-content/40">{labels.noResults}</div>
      ) : (
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
          {filtered.map((cv) => (
            <div
              key={cv.slug}
              role="button"
              tabIndex={0}
              onClick={() => openCv(cv)}
              onKeyDown={(e) => {
                if (e.key === 'Enter' || e.key === ' ') {
                  e.preventDefault();
                  openCv(cv);
                }
              }}
              className="card card-border rounded-lg bg-base-100 shadow-sm hover:shadow-md transition cursor-pointer hover:scale-105"
            >
              <figure className="relative pt-4">
                {cv.photo ? (
                  <img src={cv.photo} alt={cv.name} className="h-48 w-auto aspect-square rounded-full object-cover" loading="lazy" />
                ) : (
                  <div className="flex h-48 aspect-square rounded-full items-center justify-center bg-base-200">
                    <svg className="h-16 w-16 text-base-content/30" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true">
                      <path d="M230.92 212c-15.23-26.33-38.7-45.21-66.09-54.16a72 72 0 1 0-73.66 0C63.78 166.79 40.31 185.67 25.08 212a8 8 0 1 0 13.85 8c18.84-32.56 52.14-52 89.07-52s70.23 19.44 89.07 52a8 8 0 1 0 13.85-8Z" />
                    </svg>
                  </div>
                )}
                {cv.hasVideo && (
                  <div className="absolute bottom-3 inset-s-3">
                    <span className="badge badge-accent">{labels.video}</span>
                  </div>
                )}
              </figure>
              <div className="card-body gap-3">
                <h3 className="card-title text-lg">{cv.name}</h3>
                <div className="flex flex-wrap gap-1 text-sm text-base-content/70">
                  <span>{isoToEmojiFlag(labels.countryLabels[cv.country]?.isoCode ?? '')} {labels.countryLabels[cv.country]?.[locale]}</span>
                  <span>·</span>
                  <span>{labels.professionLabels[cv.profession]?.[locale]}</span>
                </div>
                <p className="text-sm text-base-content/60">
                  {cv.experienceYears} {labels.yearsExp}
                </p>
                <div className="flex flex-wrap gap-1">
                  {cv.skills.slice(0, 3).map((skill) => (
                    <span key={skill} className="badge badge-soft badge-secondary text-xs">{skill}</span>
                  ))}
                  {cv.skills.length > 3 && (
                    <span className="badge badge-ghost text-xs">+{cv.skills.length - 3}</span>
                  )}
                </div>
                <div className="card-actions items-center justify-end mt-1">
                  {cv.salary && (
                    <span className="text-lg bg-primary/10 px-4 py-1 rounded-2xl font-bold text-primary">
                      {cv.salary} <span className="icon-saudi_riyal"/> <span className="text-base-content/60 text-xs">{cv.priceTypeLabel ?? labels.perMonth}</span>
                    </span>
                  )}
                </div>
              </div>
            </div>
          ))}
        </div>
      )}

      <CVDetailDialog cv={selectedCv} locale={locale} labels={dialogLabels} onClose={closeCv} />
    </div>
  );
}
