"use client";

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

import Box from "@mui/material/Box";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import { keyframes } from "@mui/material/styles";

import { useAppLanguage } from "@/components/providers/app-language-provider";

const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
const UPLOAD_DURATION_MS = 2000;

const progressAnimation = keyframes`
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
`;

type Props = {
  file: File | null;

  existingFileName?: string | null;
  existingFileUrl?: string | null;

  error?: string;

  onChange: (
    file: File | null,
  ) => void;
};

export function validateCefpAttachment(
  file: File | null,
  language: string = "en",
): string | undefined {
  if (!file) {
    return undefined;
  }

  const isKhmer = language === "kh";

  const isPdf =
    file.type === "application/pdf" ||
    file.name.toLowerCase().endsWith(".pdf");

  if (!isPdf) {
    return isKhmer
      ? "អនុញ្ញាតតែឯកសារ PDF ប៉ុណ្ណោះ។"
      : "Only PDF files are allowed.";
  }

  if (file.size > MAX_FILE_SIZE_BYTES) {
    return isKhmer
      ? "ឯកសារ PDF មិនត្រូវលើស 10MB ទេ។"
      : "PDF file must not exceed 10MB.";
  }

  return undefined;
}

function formatFileSize(size: number) {
  if (size < 1024) {
    return `${size} B`;
  }

  if (size < 1024 * 1024) {
    return `${Math.round(size / 1024)} KB`;
  }

  return `${(size / (1024 * 1024)).toFixed(1)} MB`;
}

function PdfIcon() {
  return (
    <Box
      component="svg"
      viewBox="0 0 48 56"
      aria-hidden="true"
      sx={{
        width: 44,
        height: 52,
        flexShrink: 0,
      }}
    >
      <path
        d="M8 2h22l10 10v40a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Z"
        fill="none"
        stroke="#D0D5DD"
        strokeWidth="2"
      />

      <path
        d="M30 2v10h10"
        fill="none"
        stroke="#D0D5DD"
        strokeWidth="2"
      />

      <rect
        x="0"
        y="25"
        width="29"
        height="18"
        rx="3"
        fill="#F04438"
      />

      <text
        x="14.5"
        y="37"
        textAnchor="middle"
        fill="#FFFFFF"
        fontSize="10"
        fontWeight="700"
      >
        PDF
      </text>
    </Box>
  );
}

function UploadIcon() {
  return (
    <Box
      component="svg"
      viewBox="0 0 40 40"
      aria-hidden="true"
      sx={{
        width: 42,
        height: 42,
        color: "#006BB6",
      }}
    >
      <path
        d="M13 29H9.5A7.5 7.5 0 0 1 9 14a10 10 0 0 1 19.2 2.8A6 6 0 0 1 28 29h-3"
        fill="none"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="2"
      />

      <path
        d="M20 13v18M14.5 18.5 20 13l5.5 5.5"
        fill="none"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="2"
      />
    </Box>
  );
}

export function CefpAddIssueAttachmentSection({
  file,
  existingFileName = null,
  existingFileUrl = null,
  error,
  onChange,
}: Props) {
  const { language } = useAppLanguage();
  const isKhmer = language === "kh";

  const text = isKhmer
    ? {
        label: "ឯកសារភ្ជាប់បញ្ហា",
        cardTitle: "ឯកសារភ្ជាប់បញ្ហា",
        fileName: "ឯកសារភ្ជាប់",
        completed: "បានបញ្ចប់",
        uploading: "កំពុងបញ្ចូល...",
        upload: "បញ្ចូលឯកសារ",
        helper: "PDF អតិបរមា 10MB",
        currentFile: "ឯកសារបច្ចុប្បន្ន",
        replaceFile: "ប្ដូរឯកសារ",
      }
    : {
        label: "Issue Attachment",
        cardTitle: "Issue Attachment",
        fileName: "Issue attachment",
        completed: "Completed",
        uploading: "Uploading...",
        upload: "Upload file",
        helper: "PDF up to 10MB",
        currentFile: "Current file",
        replaceFile: "Replace file",
      };

  const fontFamily = isKhmer
    ? '"Battambang", "Kantumruy Pro", sans-serif'
    : '"Inter", "Segoe UI", Arial, sans-serif';

  const inputRef = useRef<HTMLInputElement | null>(null);

  const [dragActive, setDragActive] = useState(false);

  const [isUploading, setIsUploading] = useState(false);

  const [animationKey, setAnimationKey] = useState(0);

  const hasExistingFile =
    !file &&
    Boolean(
      existingFileName ||
      existingFileUrl,
    );

  const selectFile = (nextFile?: File) => {
    if (!nextFile) {
      return;
    }

    onChange(nextFile);

    const validationError = validateCefpAttachment(
      nextFile,
      language,
    );

    if (validationError) {
      setIsUploading(false);
      return;
    }

    setIsUploading(true);

    setAnimationKey((previousKey) => previousKey + 1);
  };

  const handleInputChange = (
    event: ChangeEvent<HTMLInputElement>,
  ) => {
    selectFile(event.target.files?.[0]);

    event.target.value = "";
  };

  const handleDrop = (
    event: DragEvent<HTMLDivElement>,
  ) => {
    event.preventDefault();
    event.stopPropagation();

    setDragActive(false);

    if (!isUploading) {
      selectFile(event.dataTransfer.files?.[0]);
    }
  };

  const handleKeyDown = (
    event: KeyboardEvent<HTMLDivElement>,
  ) => {
    if (
      event.key === "Enter" ||
      event.key === " "
    ) {
      event.preventDefault();

      if (!isUploading) {
        inputRef.current?.click();
      }
    }
  };

  return (
    <Box
      sx={{
        width: "100%",
        fontFamily,
      }}
    >
      <Typography
        sx={{
          mb: 1.25,
          color: "text.secondary",
          fontFamily,
          fontSize: 13,
          fontWeight: 500,
        }}
      >
        {text.label}
      </Typography>

      <input
        ref={inputRef}
        hidden
        type="file"
        accept=".pdf,application/pdf"
        onChange={handleInputChange}
      />

      <Box
        role="button"
        tabIndex={0}
        onClick={() => {
          if (!isUploading) {
            inputRef.current?.click();
          }
        }}
        onKeyDown={handleKeyDown}
        onDragEnter={(event) => {
          event.preventDefault();

          if (!isUploading) {
            setDragActive(true);
          }
        }}
        onDragOver={(event) => {
          event.preventDefault();

          if (!isUploading) {
            setDragActive(true);
          }
        }}
        onDragLeave={(event) => {
          event.preventDefault();
          setDragActive(false);
        }}
        onDrop={handleDrop}
        sx={{
          minHeight: 170,
          px: {
            xs: 2,
            sm: 2.5,
          },
          py: 2.5,

          border: "1px dashed",
          borderColor: error
            ? "error.main"
            : dragActive
              ? "primary.main"
              : "divider",

          borderRadius: 2,
          bgcolor: dragActive
            ? "action.hover"
            : "background.default",

          cursor: isUploading
            ? "default"
            : "pointer",

          outline: "none",
          transition: "all 150ms ease",

          "&:hover": {
            borderColor: isUploading
              ? "divider"
              : "primary.main",

            bgcolor: isUploading
              ? "background.default"
              : "action.hover",
          },
        }}
      >
        <Typography
          sx={{
            mb: 2,
            color: "text.primary",
            fontFamily,
            fontSize: 14,
            fontWeight: 500,
          }}
        >
          {text.cardTitle}
        </Typography>

        {file ? (
          <Box
            sx={{
              display: "flex",
              alignItems: "center",
              gap: {
                xs: 1.5,
                sm: 2,
              },
            }}
          >
            <PdfIcon />

            <Box
              sx={{
                minWidth: 0,
                flex: 1,
                display: "flex",
                alignItems: "center",
                gap: {
                  xs: 2,
                  sm: 4,
                },
              }}
            >
              <Box
                sx={{
                  minWidth: 120,
                }}
              >
                <Typography
                  title={file.name}
                  sx={{
                    maxWidth: {
                      xs: 150,
                      sm: 220,
                    },
                    overflow: "hidden",
                    color: "text.primary",
                    fontFamily,
                    fontSize: 14,
                    fontWeight: 500,
                    textOverflow: "ellipsis",
                    whiteSpace: "nowrap",
                  }}
                >
                  {file.name || text.fileName}
                </Typography>

                <Typography
                  sx={{
                    mt: 0.5,
                    color: "text.secondary",
                    fontFamily,
                    fontSize: 13,
                  }}
                >
                  {formatFileSize(file.size)}
                </Typography>
              </Box>

              <Box
                sx={{
                  minWidth: {
                    xs: 95,
                    sm: 120,
                  },
                }}
              >
                <Typography
                  sx={{
                    color: "text.secondary",
                    fontFamily,
                    fontSize: 13,
                  }}
                >
                  {isUploading
                    ? text.uploading
                    : text.completed}
                </Typography>

                <Box
                  sx={{
                    mt: 1,
                    width: {
                      xs: 80,
                      sm: 105,
                    },
                    height: 4,
                    overflow: "hidden",
                    borderRadius: 999,
                    bgcolor: "action.selected",
                  }}
                >
                  {isUploading ? (
                    <Box
                      key={animationKey}
                      onAnimationEnd={() => {
                        setIsUploading(false);
                      }}
                      sx={{
                        width: "100%",
                        height: "100%",
                        borderRadius: 999,
                        bgcolor: "#12B76A",

                        transform: "scaleX(0)",
                        transformOrigin: "left center",

                        animation: `${progressAnimation} ${UPLOAD_DURATION_MS}ms linear forwards`,
                      }}
                    />
                  ) : (
                    <Box
                      sx={{
                        width: "100%",
                        height: "100%",
                        borderRadius: 999,
                        bgcolor: "#12B76A",
                      }}
                    />
                  )}
                </Box>
              </Box>

              <IconButton
                type="button"
                aria-label={text.upload}
                disabled={isUploading}
                onClick={(event) => {
                  event.stopPropagation();

                  inputRef.current?.click();
                }}
                sx={{
                  width: 86,
                  height: 86,
                  ml: {
                    xs: 0,
                    sm: 1,
                  },
                  flexShrink: 0,

                  border: "1px dashed",
                  borderColor: "divider",
                  borderRadius: 2,

                  color: "primary.main",
                  bgcolor: "background.paper",

                  "&:hover": {
                    borderColor: "primary.main",
                    bgcolor: "action.hover",
                  },

                  "&.Mui-disabled": {
                    color: "text.disabled",
                    borderColor: "divider",
                  },
                }}
              >
                <UploadIcon />
              </IconButton>
            </Box>
          </Box>
        ) : hasExistingFile ? (
          <Box
            sx={{
              minHeight: 100,
              display: "flex",
              alignItems: "center",
              gap: {
                xs: 1.5,
                sm: 2,
              },
            }}
          >
            <PdfIcon />

            <Box
              sx={{
                minWidth: 0,
                flex: 1,
              }}
            >
              <Typography
                sx={{
                  color: "text.secondary",
                  fontFamily,
                  fontSize: 12,
                  fontWeight: 500,
                }}
              >
                {text.currentFile}
              </Typography>

              {existingFileUrl ? (
                <Typography
                  component="a"
                  href={existingFileUrl}
                  target="_blank"
                  rel="noreferrer"
                  title={
                    existingFileName ??
                    undefined
                  }
                  onClick={(event) => {
                    event.stopPropagation();
                  }}
                  sx={{
                    mt: 0.5,
                    display: "block",
                    maxWidth: {
                      xs: 260,
                      sm: 420,
                    },
                    overflow: "hidden",
                    color: "primary.main",
                    fontFamily,
                    fontSize: 14,
                    fontWeight: 600,
                    textDecoration: "none",
                    textOverflow: "ellipsis",
                    whiteSpace: "nowrap",

                    "&:hover": {
                      textDecoration:
                        "underline",
                    },
                  }}
                >
                  {existingFileName ??
                    "PDF"}
                </Typography>
              ) : (
                <Typography
                  title={
                    existingFileName ??
                    undefined
                  }
                  sx={{
                    mt: 0.5,
                    maxWidth: {
                      xs: 260,
                      sm: 420,
                    },
                    overflow: "hidden",
                    color: "text.primary",
                    fontFamily,
                    fontSize: 14,
                    fontWeight: 600,
                    textOverflow: "ellipsis",
                    whiteSpace: "nowrap",
                  }}
                >
                  {existingFileName ??
                    "PDF"}
                </Typography>
              )}

              <Typography
                sx={{
                  mt: 0.5,
                  color: "text.secondary",
                  fontFamily,
                  fontSize: 12,
                }}
              >
                {text.helper}
              </Typography>
            </Box>

            <Box
              sx={{
                flexShrink: 0,
                textAlign: "center",
              }}
            >
              <IconButton
                type="button"
                aria-label={
                  text.replaceFile
                }
                onClick={(event) => {
                  event.stopPropagation();
                  inputRef.current?.click();
                }}
                sx={{
                  width: 86,
                  height: 86,

                  border: "1px dashed",
                  borderColor: "divider",
                  borderRadius: 2,

                  color: "primary.main",
                  bgcolor:
                    "background.paper",

                  "&:hover": {
                    borderColor:
                      "primary.main",
                    bgcolor:
                      "action.hover",
                  },
                }}
              >
                <UploadIcon />
              </IconButton>

              <Typography
                sx={{
                  mt: 0.5,
                  color: "text.secondary",
                  fontFamily,
                  fontSize: 11,
                }}
              >
                {text.replaceFile}
              </Typography>
            </Box>
          </Box>
        ) : (
          <Box
            sx={{
              minHeight: 100,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              flexDirection: "column",
              textAlign: "center",
            }}
          >
            <UploadIcon />

            <Typography
              sx={{
                mt: 1,
                color: "primary.main",
                fontFamily,
                fontSize: 13,
                fontWeight: 600,
              }}
            >
              {text.upload}
            </Typography>

            <Typography
              sx={{
                mt: 0.5,
                color: "text.secondary",
                fontFamily,
                fontSize: 11,
              }}
            >
              {text.helper}
            </Typography>
          </Box>
        )}
      </Box>

      {error ? (
        <Typography
          role="alert"
          sx={{
            mt: 0.75,
            color: "error.main",
            fontFamily,
            fontSize: 12,
          }}
        >
          {error}
        </Typography>
      ) : null}
    </Box>
  );
}