import DeleteFileIcon from '@/assets/icons/DeleteFileIcon';
import SequentialFadeWrapper from '@/Components/Transition/SequentialFadeWrapper';
import DotLoader from '@/Components/ui/dotloader';
import { AdminSettingKey } from '@/enum/settings-menu';
import AdminLayoutWithProviders from '@/Layouts/AdminLayout';
import AdminSettingsLayout from '@/Layouts/AdminSettingsLayout';
import type { ReadingSkillImportRecord } from '@/types/reading-skill';
import { router } from '@inertiajs/react';
import { useRef, useState } from 'react';

interface SkillsProps {
  lastImport: ReadingSkillImportRecord | null;
}

export default function Skills({ lastImport }: SkillsProps) {
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [footerStep, setFooterStep] = useState<'default' | 'uploading' | 'success' | 'error'>(
    'default'
  );
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [isDeleteClicked, setIsDeleteClicked] = useState(false);
  const [isDeleteHovered, setIsDeleteHovered] = useState(false);

  const fileInputRef = useRef<HTMLInputElement>(null);
  const [initialFileName, setInitialFileName] = useState(lastImport?.original_filename ?? null);

  const handleFileSelect = () => fileInputRef.current?.click();

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    const isZip = file.type === 'application/zip' || file.name.endsWith('.zip');
    if (!isZip) {
      alert('Please select a ZIP file');
      return;
    }

    setSelectedFile(file);
  };

  const handleRemoveFile = () => {
    setSelectedFile(null);
    if (fileInputRef.current) fileInputRef.current.value = '';
  };

  const handleRemoveExisting = () => {
    setSelectedFile(null);
    setInitialFileName(null);
    if (fileInputRef.current) fileInputRef.current.value = '';
  };

  const handleSave = () => {
    if (!selectedFile) return;

    setErrorMessage(null);
    setFooterStep('uploading');

    const formData = new FormData();
    formData.append('file', selectedFile);

    router.post(route('admin.settings.skills.import'), formData, {
      forceFormData: true,
      onSuccess: () => {
        setInitialFileName(selectedFile.name);
        setSelectedFile(null);
        if (fileInputRef.current) fileInputRef.current.value = '';
        setFooterStep('success');
      },
      // The parser reports every problem in the file at once, but Inertia
      // surfaces only the first message per field, so the footer shows one.
      onError: (errors) => {
        setErrorMessage(errors.file ?? 'Error: The reading skill package could not be uploaded.');
        setFooterStep('error');
      },
    });
  };

  return (
    <AdminSettingsLayout nav={AdminSettingKey.Skills}>
      <div className="flex h-full flex-col justify-between">
        <div className="flex flex-1 flex-col">
          <div className="m-0 mb-[8px] flex items-center justify-between p-0">
            <h1 className="flex translate-y-[-1px] items-center font-readingful text-[2.4rem] font-bold leading-none text-[#6F8AE2]">
              Settings
            </h1>
          </div>
          <p className="mb-[15px] font-readingful text-[2.0rem] font-bold text-[#B7C7F7]">
            Skills
          </p>

          <SequentialFadeWrapper
            transitionKey={selectedFile || initialFileName ? 'file' : 'no-file'}
            duration={300}
            className="mb-[15px] flex flex-row gap-[5px] self-start"
          >
            {selectedFile || initialFileName ? (
              <>
                <div className="h-[50px] cursor-default rounded-full bg-[#94B8FF] px-8 py-[8.5px] font-readingful text-[2.2rem] font-semibold text-white">
                  {selectedFile ? selectedFile.name : initialFileName}
                </div>

                <button
                  onClick={selectedFile ? handleRemoveFile : handleRemoveExisting}
                  onMouseEnter={() => setIsDeleteHovered(true)}
                  onMouseLeave={() => setIsDeleteHovered(false)}
                  onMouseDown={() => setIsDeleteClicked(true)}
                  onMouseUp={() => setIsDeleteClicked(false)}
                  className="self-start px-1"
                >
                  <DeleteFileIcon
                    className="h-[14px] w-[14px] transition-colors duration-150"
                    fill={isDeleteClicked ? '#E2E8F780' : isDeleteHovered ? '#E2E8F7BF' : '#E2E8F7'}
                  />
                </button>
              </>
            ) : (
              <button
                onClick={handleFileSelect}
                className="mb-0 h-[50px] w-[150px] rounded-full bg-[#e2e8f7] font-readingful text-[2.2rem] font-semibold text-white transition hover:bg-[#e2e8f7]/75 active:bg-[#e2e8f7]/50"
              >
                Select File
              </button>
            )}
          </SequentialFadeWrapper>

          {/* Hidden Input */}
          <input
            ref={fileInputRef}
            type="file"
            accept=".zip,application/zip"
            className="hidden"
            onChange={handleFileChange}
          />

          <p className="mb-auto max-w-[600px] font-readmore text-[16px] leading-tight text-[#576082]">
            Upload the schema package ZIP file that contains the full <br /> organizational mapping of
            reading concepts and skills.
          </p>
        </div>

        <SequentialFadeWrapper
          transitionKey={footerStep}
          duration={400}
          className="flex w-full items-center justify-between"
        >
          {footerStep === 'uploading' ? (
            <>
              <p className="translate-y-[5px] self-end font-readmore text-[16px] text-[#BFC6DD]">
                Uploading reading skill package...
              </p>
              <DotLoader dotColor="#85A8FF" size="xl" className="translate-y-[6px]" />
            </>
          ) : footerStep === 'error' ? (
            <>
              <p className="translate-y-[5px] self-end font-readmore text-[16px] text-[#B4565B]">
                {errorMessage}
              </p>
              <button
                onClick={handleSave}
                disabled={!selectedFile}
                className={`h-[50px] w-[90px] rounded-full bg-[#6c96ff] py-3 font-readingful text-[22px] leading-none text-[#FFFFFF] transition duration-150 hover:opacity-75 active:opacity-50 disabled:opacity-50
                                        ${selectedFile !== null ? ' cursor-pointer' : ''}`}
              >
                Save
              </button>
            </>
          ) : footerStep === 'success' ? (
            <>
              <p className="translate-y-[5px] self-end font-readmore text-[16px] text-[#BFC6DD]">
                Reading skill package successfully uploaded.
              </p>
              <button
                onClick={handleSave}
                disabled={!selectedFile}
                className={`h-[50px] w-[90px]  rounded-full bg-[#6c96ff] py-3 font-readingful text-[22px] leading-none text-[#FFFFFF] transition duration-150 hover:opacity-75 active:opacity-50 disabled:opacity-50
                                        ${selectedFile !== null ? ' cursor-pointer' : ''}`}
              >
                Save
              </button>
            </>
          ) : (
            <>
              <p className="h-[22px] translate-y-[7px] content-end self-end font-readmore text-[16px] leading-none text-[#BFC6DD]">
                Contents should be formatted as a tab-delimited text file.
              </p>
              <button
                onClick={handleSave}
                disabled={!selectedFile}
                className={`h-[50px] w-[90px] rounded-full bg-[#6c96ff] py-3 font-readingful text-[22px] leading-none text-[#FFFFFF] transition duration-150 hover:opacity-75 active:opacity-50 disabled:opacity-50
                                        ${selectedFile !== null ? ' cursor-pointer' : ''}`}
              >
                Save
              </button>
            </>
          )}
        </SequentialFadeWrapper>
      </div>
    </AdminSettingsLayout>
  );
}

Skills.layout = (page: React.ReactElement) => (
  <AdminLayoutWithProviders>{page}</AdminLayoutWithProviders>
);
