import { useState } from 'react';
import { useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { fetchFormats, uploadFiles } from '../api.js';
import { FileCard } from '../FileCard.jsx';
import { Dropzone } from '../components/Dropzone.jsx';
import { FileConfigCard } from '../components/FileConfigCard.jsx';
import { ReassuranceStrip } from '../components/ReassuranceStrip.jsx';
import { FormatsGrid } from '../components/FormatsGrid.jsx';
import { FormatMarquee } from '../components/FormatMarquee.jsx';
import { SeoHead } from '../components/SeoHead.jsx';
import { extensionOf } from '../utils/archiveExtensions.js';
import '../styles/home.css';
import '../styles/sections.css';

const DEFAULT_QUALITY = {
  jpg: 80,
  jpeg: 80,
  webp: 80,
  avif: 50,
  tiff: 80,
  png: 6,
  zip: 6,
  'tar.gz': 6,
  'tar.bz2': 9,
  '7z': 5,
  'tar.7z': 5,
  mp3: 192,
  ogg: 192,
  aac: 192,
  m4a: 192,
};

const DEFAULT_ICON_SIZE = 256;

function defaultQualityFor(targetFormat) {
  return DEFAULT_QUALITY[targetFormat] ?? null;
}

export function HomePage() {
  const { lang } = useParams();
  const { t } = useTranslation();
  const [pendingFiles, setPendingFiles] = useState([]);
  const [submittedJobs, setSubmittedJobs] = useState([]);

  async function handleFilesSelected(fileList) {
    const files = Array.from(fileList);
    const withTargets = await Promise.all(
      files.map(async (file) => {
        const targets = await fetchFormats(extensionOf(file.name));
        const targetFormat = targets[0] ?? null;
        return {
          file,
          targets,
          targetFormat,
          quality: defaultQualityFor(targetFormat),
          iconSize: targetFormat === 'ico' ? DEFAULT_ICON_SIZE : null,
        };
      })
    );
    setPendingFiles((current) => [...current, ...withTargets]);
  }

  function updateTargetFormat(index, targetFormat) {
    setPendingFiles((current) =>
      current.map((item, i) =>
        i === index
          ? {
              ...item,
              targetFormat,
              quality: defaultQualityFor(targetFormat),
              iconSize: targetFormat === 'ico' ? DEFAULT_ICON_SIZE : null,
            }
          : item
      )
    );
  }

  function updateQuality(index, quality) {
    setPendingFiles((current) => current.map((item, i) => (i === index ? { ...item, quality } : item)));
  }

  function updateIconSize(index, iconSize) {
    setPendingFiles((current) => current.map((item, i) => (i === index ? { ...item, iconSize } : item)));
  }

  function removePendingFile(index) {
    setPendingFiles((current) => current.filter((_, i) => i !== index));
  }

  function removeSubmittedJob(index) {
    setSubmittedJobs((current) => current.filter((_, i) => i !== index));
  }

  async function handleConvert() {
    const validItems = pendingFiles.filter((item) => item.targetFormat);
    const jobs = await uploadFiles(validItems);
    const jobsWithSize = jobs.map((job, i) => ({
      ...job,
      size: validItems[i].file.size,
      targetFormat: validItems[i].targetFormat,
    }));
    setSubmittedJobs((current) => [...current, ...jobsWithSize]);
    setPendingFiles([]);
  }

  return (
    <>
      <SeoHead lang={lang} />
      <section className="hero">
        <div className="hero-aurora" aria-hidden="true" />
        <div className="hero-content">
          <span className="hero-kicker">{t('hero.kicker')}</span>
          <h1 className="hero-title">{t('hero.title')}</h1>
          <p>{t('hero.subtitle')}</p>
          <Dropzone label={t('hero.dropzoneLabel')} onFilesSelected={handleFilesSelected} />
          <FormatMarquee />

          {pendingFiles.length > 0 && (
            <div className="pending-files">
              <ul>
                {pendingFiles.map((item, index) => (
                  <FileConfigCard
                    key={`${item.file.name}-${index}`}
                    item={item}
                    index={index}
                    t={t}
                    onTargetFormatChange={updateTargetFormat}
                    onQualityChange={updateQuality}
                    onIconSizeChange={updateIconSize}
                    onRemove={removePendingFile}
                  />
                ))}
              </ul>
              <button className="convert-button" onClick={handleConvert}>
                {t('hero.convert')}
              </button>
            </div>
          )}

          <ul className="job-list">
            {submittedJobs.map((job, index) =>
              job.id ? (
                <FileCard
                  key={job.id}
                  fileName={job.file}
                  fileSize={job.size}
                  targetFormat={job.targetFormat}
                  jobId={job.id}
                  onRemove={() => removeSubmittedJob(index)}
                />
              ) : (
                <FileCard
                  key={`${job.file}-${index}`}
                  fileName={job.file}
                  fileSize={job.size}
                  targetFormat={job.targetFormat}
                  initialError={job.error}
                  onRemove={() => removeSubmittedJob(index)}
                />
              )
            )}
          </ul>
        </div>
      </section>

      <ReassuranceStrip />
      <FormatsGrid />
    </>
  );
}
