import { Card, Text, Table, Badge, ActionIcon, Drawer, Box, Group, Stack, Alert } from '@pikku/mantine/core';
import { IconArrowRight, IconEye, IconMaximize, IconMinimize, IconPlus, IconRotateClockwise, IconX } from '@tabler/icons-react';
import React, { useState, useEffect, useRef } from 'react';
import type { DB } from '@heygermany/sdk';
import { DocumentStatuses } from '@heygermany/sdk';
import { getFieldComponent } from './DocumentFieldFactory';
import { pikku } from '@/pikku/http';
import { useUpdateDocumentVerification } from '@/hooks/backoffice/useUpdateDocumentVerification';
import { useUploadBackOfficeCandidateFiles } from '@/hooks/backoffice/useUploadBackOfficeCandidateFiles';
import { UseMutationResult } from '@tanstack/react-query';
import { DocumentStatusSelect } from './DocumentStatusSelect';
import { useI18n } from '@/context/i18n-provider';
import { asI18n } from '@pikku/react';

type VerificationDocument = {
  documentId: string;
  documentStatus: DB.DocumentStatus | null;
  label?: string;
};

type DocumentVerificationCardProps = {
  category: DB.CandidateDocumentType;
  candidateId: string;
  documents: VerificationDocument[];
  aiExtractedData: Record<string, any>;
  finalData: Record<string, any>;
  mutationHook: UseMutationResult<any, Error, any, unknown>;
  verbose?: boolean;
  requiredFields?: string[];
};

export function DocumentVerificationCard({
  candidateId,
  documents,
  category,
  aiExtractedData,
  finalData,
  mutationHook,
  verbose = false,
  requiredFields = [],
}: DocumentVerificationCardProps) {
  const [documentUrl, setDocumentUrl] = useState<string | null>(null);
  const [documentPreviewTitle, setDocumentPreviewTitle] = useState('Document Preview');
  const [formData, setFormData] = useState<Record<string, any>>({});
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [rotation, setRotation] = useState(0);
  const [isUploading, setIsUploading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const [deletingDocumentId, setDeletingDocumentId] = useState<string | null>(null);
  const [deleteError, setDeleteError] = useState<string | null>(null);
  const updateDocumentVerification = useUpdateDocumentVerification(candidateId);
  const { uploadFiles, deleteFile } = useUploadBackOfficeCandidateFiles(candidateId, category);
  const t = useI18n();
  const fileInputRef = useRef<HTMLInputElement | null>(null);

  const showDocument = async (documentId: string, label: string) => {
    const response = await pikku().get('/backoffice/candidate/:candidateId/document/:documentId', { documentId, candidateId });
    setDocumentPreviewTitle(label);
    setDocumentUrl(response.url)
  }

  const allFields = new Set([
    ...Object.keys(aiExtractedData || {}),
    ...Object.keys(finalData || {})
  ]);

  // Show only required fields when not in verbose mode
  const fieldsToShow = verbose
    ? Array.from(allFields)
    : requiredFields.filter(field => allFields.has(field));

  const getFieldLabel = (fieldName: string) => {
    return fieldName.charAt(0).toUpperCase() + fieldName.slice(1).replace(/([A-Z])/g, ' $1');
  };

  useEffect(() => {
    setFormData({ ...finalData });
  }, [finalData]);

  const handleCopyOver = (fieldName: string) => {
    const aiValue = aiExtractedData?.[fieldName];
    if (aiValue !== undefined) {
      const updatedData = { ...formData, [fieldName]: aiValue };
      setFormData(updatedData);
      mutationHook.mutate({ [fieldName]: aiValue });
    }
  };

  const handleFieldChange = (fieldName: string, value: any) => {
    setFormData((currentData) => ({
      ...currentData,
      [fieldName]: value,
    }));
    mutationHook.mutate({ [fieldName]: value });
  };

  const handleFileSelection = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFiles = Array.from(event.target.files || []);

    if (!selectedFiles.length) {
      return;
    }

    setUploadError(null);
    setIsUploading(true);

    try {
      await uploadFiles(selectedFiles);
    } catch (error) {
      console.error('Error uploading files in backoffice:', error);
      setUploadError('Failed to upload document(s). Please try again.');
    } finally {
      setIsUploading(false);
      event.target.value = '';
    }
  };

  const handleDeleteDocument = async (documentId: string, label: string) => {
    const confirmed = window.confirm(`Delete ${label}?`);

    if (!confirmed) {
      return;
    }

    setDeleteError(null);
    setDeletingDocumentId(documentId);

    try {
      await deleteFile(documentId);
    } catch (error) {
      console.error('Error deleting file in backoffice:', error);
      setDeleteError('Failed to delete document. Please try again.');
    } finally {
      setDeletingDocumentId(null);
    }
  };

  return (
    <>
      <Card shadow="sm" px={0} pb={0} radius="md" withBorder>
        <Card.Section withBorder inheritPadding py="sm">
          <Stack gap="sm" px="md">
            <input
              ref={fileInputRef}
              type="file"
              accept=".pdf,.jpg,.jpeg,.png"
              multiple
              hidden
              onChange={handleFileSelection}
            />
            {documents.length > 0 ? (
              documents.map((document, index) => {
                const label = document.label || `Document ${index + 1}`;
                return (
                  <Group key={`${document.documentId}-${index}`} justify="space-between">
                    <Group gap="xs">
                      <Badge
                        color="blue"
                        variant="light"
                        style={{ cursor: 'pointer' }}
                        onClick={() => showDocument(document.documentId, label)}
                      >
                        {asI18n(label)}
                      </Badge>
                      <ActionIcon
                        variant="subtle"
                        color="red"
                        size="sm"
                        onClick={() => handleDeleteDocument(document.documentId, label)}
                        disabled={deletingDocumentId === document.documentId}
                        aria-label={asI18n(`Delete ${label}`)}
                        title={asI18n(`Delete ${label}`)}
                      >
                        <IconX size={14} />
                      </ActionIcon>
                    </Group>
                    <DocumentStatusSelect
                      value={document.documentStatus ?? DocumentStatuses.UNVERIFIED}
                      onChange={(status) => updateDocumentVerification.mutate({
                        documentId: document.documentId,
                        documentStatus: status
                      })}
                    />
                  </Group>
                );
              })
            ) : (
              <Text size="sm" c="dimmed">{t('backoffice.documents.nofilesavailable' as any)}</Text>
            )}
            <Badge
              color="blue"
              variant="light"
              style={{
                cursor: isUploading ? 'default' : 'pointer',
                alignSelf: 'flex-start',
                opacity: isUploading ? 0.7 : 1,
              }}
              onClick={isUploading ? undefined : () => fileInputRef.current?.click()}
            >
              <Group gap={4} wrap="nowrap">
                <IconPlus size={12} />
                <Text size="xs" inherit>{asI18n(isUploading ? t('backoffice.documents.uploading' as any) : t('backoffice.documents.uploaddocuments' as any))}</Text>
              </Group>
            </Badge>
            {uploadError ? (
              <Alert color="red" variant="light">
                {asI18n(uploadError)}
              </Alert>
            ) : null}
            {deleteError ? (
              <Alert color="red" variant="light">
                {asI18n(deleteError)}
              </Alert>
            ) : null}
          </Stack>
        </Card.Section>

        {fieldsToShow.length > 0 ? (
          <Table>
            <Table.Thead>
              <Table.Tr>
                <Table.Th>Field</Table.Th>
                <Table.Th>AI Value</Table.Th>
                <Table.Th></Table.Th>
                <Table.Th>User Value</Table.Th>
              </Table.Tr>
            </Table.Thead>
            <Table.Tbody>
              {fieldsToShow.map((fieldName) => {
              const FieldComponent = getFieldComponent(category, fieldName);

              return (
                <Table.Tr key={fieldName}>
                  <Table.Td>
                    <Text size="sm" fw={500}>
                      {asI18n(getFieldLabel(fieldName))}
                    </Text>
                  </Table.Td>
                  <Table.Td>
                    <FieldComponent
                      value={aiExtractedData?.[fieldName]}
                      onChange={() => { }} // Read-only
                      disabled={true}
                    />
                  </Table.Td>
                  <Table.Td>
                    <ActionIcon
                      variant="light"
                      size="sm"
                      onClick={() => handleCopyOver(fieldName)}
                      disabled={!aiExtractedData?.[fieldName]}
                    >
                      <IconArrowRight size={14} />
                    </ActionIcon>
                  </Table.Td>
                  <Table.Td>
                    <FieldComponent
                      value={formData?.[fieldName]}
                      onChange={(value) => handleFieldChange(fieldName, value)}
                    />
                  </Table.Td>
                </Table.Tr>
              );
            })}
          </Table.Tbody>
        </Table>
        ) : (
          <Box p="md" ta="center">
            <Text c="dimmed" size="sm">{asI18n('No required fields')}</Text>
          </Box>
        )}
      </Card>

      <Drawer
        opened={!!documentUrl}
        onClose={() => {
          setDocumentUrl(null);
          setIsFullscreen(false);
          setRotation(0);
        }}
        position="right"
        size={isFullscreen ? "100%" : "60%"}
        title={
          <Group justify="space-between" style={{ width: '100%', paddingRight: '1rem' }}>
            <Text>{asI18n(documentPreviewTitle)}</Text>
            <Group gap="xs">
              <ActionIcon
                variant="light"
                onClick={() => setRotation((prev) => (prev + 90) % 360)}
                title={asI18n('Rotate image')}
              >
                <IconRotateClockwise size={18} />
              </ActionIcon>
              <ActionIcon
                variant="light"
                onClick={() => setIsFullscreen(!isFullscreen)}
                title={asI18n(isFullscreen ? 'Exit fullscreen' : 'Fullscreen')}
              >
                {isFullscreen ? <IconMinimize size={18} /> : <IconMaximize size={18} />}
              </ActionIcon>
            </Group>
          </Group>
        }
      >
        {documentUrl && (
          <Box style={{ height: '100%' }}>
            <iframe
              src={documentUrl}
              style={{
                width: '100%',
                height: 'calc(100vh - 100px)',
                border: 'none',
                transform: `rotate(${rotation}deg)`,
                transformOrigin: 'center center',
                transition: 'transform 0.3s ease'
              }}
              title={asI18n('Document Preview')}
            />
          </Box>
        )}
      </Drawer>
    </>
  );
}
