"use client";

import { useId, useState, type ChangeEvent, type DragEvent } from "react";

import Alert from "@mui/material/Alert";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";

import CloudDownloadOutlinedIcon from "@mui/icons-material/CloudDownloadOutlined";

import { useAppLanguage } from "@/components/providers/app-language-provider";
import { DocumentLink } from "@/components/ui/document-link";
import { DocumentFileName } from "@/components/ui/document-file-name";
import { getFormBorderColor, getFormSoftBg } from "@/components/ui/form";
import { PdfIcon } from "@/components/ui/icon";
import {
  formatFileSize,
  getDisplayFileName,
  type UploadedFileMetadata,
} from "@/lib/document-file";

import {
  canMinistryUploadDocument,
  type ApiMinistryProgressReportAssignment,
} from "../../service/progress-report-service";

const PDF_ACCEPT = ".pdf,application/pdf";
const MAX_PDF_SIZE_BYTES = 10 * 1024 * 1024;

type ProgressReportDocumentSectionProps = {
  attachment: UploadedFileMetadata | null;
  assignmentStatus: ApiMinistryProgressReportAssignment["status"];
  isUploading?: boolean;
  onUpload: (file: File) => Promise<void>;
};

function ReplaceUploadControl({
  inputId,
  disabled,
  onFileChange,
  onDrop,
  onDragOver,
}: {
  inputId: string;
  disabled: boolean;
  onFileChange: (event: ChangeEvent<HTMLInputElement>) => void;
  onDrop: (event: DragEvent<HTMLLabelElement>) => void;
  onDragOver: (event: DragEvent<HTMLLabelElement>) => void;
}) {
  const theme = useTheme();

  return (
    <Box
      component="label"
      htmlFor={inputId}
      onDragOver={onDragOver}
      onDrop={onDrop}
      sx={{
        width: 77,
        height: 62,
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        flexShrink: 0,
        border: `1px dashed ${getFormBorderColor(theme)}`,
        borderRadius: "12px",
        bgcolor: getFormSoftBg(theme),
        cursor: disabled ? "default" : "pointer",
        opacity: disabled ? 0.72 : 1,
        transition: "0.2s",
        ...(!disabled
          ? {
              "&:hover": {
                bgcolor: alpha(theme.palette.primary.main, 0.1),
                borderColor: theme.palette.primary.main,
              },
            }
          : {}),
      }}
    >
      <CloudDownloadOutlinedIcon
        sx={{ fontSize: 38, color: theme.palette.primary.main }}
      />
    </Box>
  );
}

export function ProgressReportDocumentSection({
  attachment,
  assignmentStatus,
  isUploading = false,
  onUpload,
}: ProgressReportDocumentSectionProps) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const { language } = useAppLanguage();
  const inputId = useId();
  const [validationError, setValidationError] = useState<string | null>(null);
  const [uploadError, setUploadError] = useState<string | null>(null);

  const canUpload = canMinistryUploadDocument(assignmentStatus);
  const isBusy = isUploading;
  const replaceEnabled = canUpload && !isBusy;

  async function handleFileSelect(file: File) {
    if (!canUpload || isBusy) return;

    if (file.type !== "application/pdf" && !file.name.toLowerCase().endsWith(".pdf")) {
      setValidationError("Only PDF files are supported.");
      return;
    }

    if (file.size > MAX_PDF_SIZE_BYTES) {
      setValidationError("PDF file must be 10 MB or smaller.");
      return;
    }

    setValidationError(null);
    setUploadError(null);

    try {
      await onUpload(file);
    } catch (error) {
      setUploadError(
        error instanceof Error
          ? error.message
          : "Unable to upload the progress document.",
      );
    }
  }

  function handleFileChange(event: ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];
    if (file) {
      void handleFileSelect(file);
    }
    event.target.value = "";
  }

  function handleDrop(event: DragEvent<HTMLLabelElement>) {
    event.preventDefault();
    if (!replaceEnabled) return;

    const file = event.dataTransfer.files?.[0];
    if (file) {
      void handleFileSelect(file);
    }
  }

  function handleDragOver(event: DragEvent<HTMLLabelElement>) {
    event.preventDefault();
  }

  function handleEmptyDrop(event: DragEvent<HTMLLabelElement>) {
    event.preventDefault();
    if (!replaceEnabled) return;

    const file = event.dataTransfer.files?.[0];
    if (file) {
      void handleFileSelect(file);
    }
  }

  const displayName = attachment
    ? getDisplayFileName(attachment.name, "Progress Document")
    : null;
  const errorMessage = validationError || uploadError;
  const fileSizeLabel = attachment
    ? formatFileSize(attachment.size, language)
    : null;

  const fileCard = (
    <Box
      sx={{
        width: { xs: "100%", sm: 287 },
        height: 62,
        px: 1.625,
        display: "flex",
        alignItems: "center",
        gap: 1.5,
        borderRadius: "6px",
        bgcolor: getFormSoftBg(theme),
        overflow: "hidden",
      }}
    >
      <PdfIcon sx={{ fontSize: 40, flexShrink: 0 }} />

      <Box sx={{ minWidth: 0, flex: 1 }}>
        <DocumentFileName
          name={displayName ?? "-"}
          fontSize={12}
          fontWeight={500}
          color={isDark ? "#f9fafb" : "#252b37"}
        />
        <Typography
          sx={{
            mt: 1.5,
            fontSize: 12,
            lineHeight: 1.24,
            color: isDark ? "#d0d5dd" : "#414651",
          }}
        >
          {fileSizeLabel}
        </Typography>
      </Box>

      {isBusy ? (
        <Box sx={{ width: 80, flexShrink: 0, textAlign: "center" }}>
          <Typography
            sx={{
              mb: 1,
              fontSize: 11,
              lineHeight: "16px",
              fontWeight: 500,
              color: isDark ? "#98a2b3" : "#868686",
            }}
          >
            Uploading
          </Typography>
          <Box
            sx={{
              width: 80,
              height: 4,
              borderRadius: "16px",
              bgcolor: theme.palette.background.paper,
              overflow: "hidden",
            }}
          >
            <Box
              sx={{
                width: "45%",
                height: "100%",
                borderRadius: "16px",
                bgcolor: "#22C55E",
                animation: "progressReportUploadPulse 1.2s ease-in-out infinite",
                "@keyframes progressReportUploadPulse": {
                  "0%": { width: "20%" },
                  "50%": { width: "70%" },
                  "100%": { width: "20%" },
                },
              }}
            />
          </Box>
        </Box>
      ) : null}
    </Box>
  );

  return (
    <Box sx={{ minWidth: 0 }}>
      <Typography
        sx={{
          mb: 1.5,
          fontSize: 13,
          fontWeight: 500,
          color: isDark ? "#d0d5dd" : "#414651",
        }}
      >
        Progress Document{" "}
        <Box component="span" sx={{ color: "#f04438" }}>
          *
        </Box>
      </Typography>

      <input
        id={inputId}
        type="file"
        accept={PDF_ACCEPT}
        onChange={handleFileChange}
        disabled={!replaceEnabled}
        style={{ display: "none" }}
      />

      {attachment && displayName ? (
        <Box
          sx={{
            display: "flex",
            flexWrap: "wrap",
            alignItems: "center",
            gap: "22px",
          }}
        >
          {canUpload ? (
            fileCard
          ) : (
            <DocumentLink file={attachment} sx={{ display: "block", minWidth: 0 }}>
              {fileCard}
            </DocumentLink>
          )}

          {canUpload ? (
            <ReplaceUploadControl
              inputId={inputId}
              disabled={!replaceEnabled}
              onFileChange={handleFileChange}
              onDrop={handleDrop}
              onDragOver={handleDragOver}
            />
          ) : null}
        </Box>
      ) : (
        <Box
          component="label"
          htmlFor={inputId}
          onDragOver={handleDragOver}
          onDrop={handleEmptyDrop}
          sx={{
            height: 135,
            border: `1px dashed ${isDark ? alpha("#ffffff", 0.16) : getFormBorderColor(theme)}`,
            borderRadius: "10px",
            bgcolor: getFormSoftBg(theme),
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            flexDirection: "column",
            cursor: replaceEnabled ? "pointer" : "default",
            opacity: canUpload ? 1 : 0.72,
            transition: "0.2s",
            ...(!replaceEnabled
              ? {}
              : {
                  "&:hover": {
                    bgcolor: alpha(theme.palette.primary.main, 0.1),
                    borderColor: theme.palette.primary.main,
                  },
                }),
          }}
        >
          <CloudDownloadOutlinedIcon
            sx={{
              mb: 0.5,
              fontSize: 34,
              color: theme.palette.primary.main,
            }}
          />

          <Typography
            sx={{
              fontSize: 11,
              color: theme.palette.text.secondary,
              fontWeight: 600,
            }}
          >
            <Box
              component="span"
              sx={{ color: theme.palette.primary.main, fontWeight: 700 }}
            >
              Click to upload
            </Box>{" "}
            or drag and drop
          </Typography>

          <Typography
            sx={{ fontSize: 10, color: theme.palette.text.secondary }}
          >
            pdf 10MB
          </Typography>
        </Box>
      )}

      {errorMessage ? (
        <Alert severity="error" sx={{ mt: 1.5 }}>
          {errorMessage}
        </Alert>
      ) : null}
    </Box>
  );
}
