import { TextInput, Select, Textarea, NumberInput, Group, Text, MultiSelect } from '@pikku/mantine/core';
import { DateInput } from '@mantine/dates';
import {
  ApplicantStatuses,
  CandidateDocumentTypes,
  LanguageLevels,
  NurseRecognitionGermanyValues,
  NurseRecognitionHomeCountryValues,
} from '@heygermany/sdk';
import React from 'react';
import { EnumSelect } from '@/components/common/EnumSelect';
import { useI18n } from '@/context/i18n-provider';
import { asI18n } from '@pikku/react';

export type FieldComponentProps = {
  value: any;
  onChange: (value: any) => void;
  label?: any;
  placeholder?: any;
  disabled?: boolean;
};

export type FieldComponent = (props: FieldComponentProps) => React.ReactElement;

// Reusable component functions
export const TextInputComponent: FieldComponent = ({ value, onChange, label, placeholder, disabled }) => (
  <TextInput
    value={value || ''}
    onChange={(e) => onChange(e.target.value)}
    label={label as any}
    placeholder={placeholder as any}
    disabled={disabled}
  />
);

export const TextareaComponent: FieldComponent = ({ value, onChange, label, placeholder, disabled }) => (
  <Textarea
    value={value || ''}
    onChange={(e) => onChange(e.target.value)}
    label={label as any}
    placeholder={placeholder as any}
    disabled={disabled}
    autosize
    minRows={2}
  />
);

export const NumberInputComponent: FieldComponent = ({ value, onChange, label, placeholder, disabled }) => (
  <NumberInput
    value={value || undefined}
    onChange={onChange}
    label={label as any}
    placeholder={placeholder as any}
    disabled={disabled}
  />
);

export const DateInputComponent: FieldComponent = ({ value, onChange, label, placeholder, disabled }) => (
  <DateInput
    value={value ? new Date(value) : null}
    onChange={(date: string | null) => onChange(date)}
    label={label as any}
    placeholder={placeholder as any}
    disabled={disabled}
    valueFormat="YYYY-MM-DD"
  />
);

export const LanguageLevelSelectComponent: FieldComponent = ({ value, onChange, label, disabled }) => {
  const t = useI18n();
  return (
    <EnumSelect
      enumObject={LanguageLevels}
      enumName="LanguageLevel"
      value={value || null}
      onChange={onChange}
      label={label}
      placeholder={t('backoffice.filters.selectlevel')}
      disabled={disabled}
    />
  );
};

export const BooleanSelectComponent: FieldComponent = ({ value, onChange, label, disabled }) => {
  const t = useI18n();
  const options = [
    { value: 'true', label: t('common.yes') },
    { value: 'false', label: t('common.no') },
    { value: 'null', label: t('backoffice.filters.unknown') }
  ];

  const getCurrentValue = () => {
    if (value === true) return 'true';
    if (value === false) return 'false';
    return 'null';
  };

  const handleChange = (newValue: string | null) => {
    if (newValue === 'true') onChange(true);
    else if (newValue === 'false') onChange(false);
    else onChange(null);
  };

  return (
    <Select
      value={getCurrentValue()}
      onChange={handleChange}
      label={label as any}
      placeholder={t('backoffice.filters.select')}
      disabled={disabled}
      data={options}
      styles={{
        input: {
          ...(value === null && !disabled ? {
            borderColor: '#FFA500',
            borderWidth: '2px'
          } : {})
        }
      }}
    />
  );
};

export const StringArrayComponent: FieldComponent = ({ value, onChange, label, disabled }) => {
  const t = useI18n();
  const arrayValue = Array.isArray(value) ? value : [];

  return (
    <Group gap="xs" align="flex-start">
      <Text size="sm" fw={500}>{asI18n(String(label ?? ''))}</Text>
      <Textarea
        value={arrayValue.join('\n')}
        onChange={(e) => onChange(e.target.value.split('\n').filter(item => item.trim()))}
        placeholder={t('backoffice.filters.oneitemperline')}
        disabled={disabled}
        autosize
        minRows={2}
        style={{ flex: 1 }}
      />
    </Group>
  );
};

export const NurseRecognitionGermanySelectComponent: FieldComponent = ({ value, onChange, label, disabled }) => {
  const t = useI18n();
  return (
    <EnumSelect
      enumObject={NurseRecognitionGermanyValues}
      enumName="NurseRecognitionGermany"
      value={value || null}
      onChange={onChange}
      label={label}
      placeholder={t('backoffice.filters.selectrecognitionlevel')}
      disabled={disabled}
    />
  );
};

export const NurseRecognitionHomeCountrySelectComponent: FieldComponent = ({ value, onChange, label, disabled }) => {
  const t = useI18n();
  return (
    <EnumSelect
      enumObject={NurseRecognitionHomeCountryValues}
      enumName="NurseRecognitionHomeCountry"
      value={value || null}
      onChange={onChange}
      label={label}
      placeholder={t('backoffice.filters.selectrecognitionlevel')}
      disabled={disabled}
    />
  );
};

export const ApplicantStatusSelectComponent: FieldComponent = ({ value, onChange, label, placeholder, disabled }) => {
  const t = useI18n();
  return (
    <EnumSelect
      enumObject={ApplicantStatuses}
      enumName="ApplicantStatus"
      value={value || null}
      onChange={onChange}
      label={label}
      placeholder={placeholder || t('backoffice.candidate.fields.selectstatus')}
      disabled={disabled}
    />
  );
};

export const WhatItMeansSelectComponent: FieldComponent = ({ value, onChange, label, disabled }) => {
  const t = useI18n();
  // Define the enum values based on the SQL schema
  const WhatItMeansEnum = {
    PARTIAL_RECOGNITION_B_ONE: 'PARTIAL_RECOGNITION_B_ONE',
    PARTIAL_RECOGNITION_B_TWO: 'PARTIAL_RECOGNITION_B_TWO',
    NONE: 'NONE',
  } as const;

  const whatItMeansOptions = Object.values(WhatItMeansEnum).map(meaning => ({
    value: meaning,
    label: meaning.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, l => l.toUpperCase())
  }));

  return (
    <Select
      value={value || null}
      onChange={onChange}
      label={label as any}
      placeholder={t('backoffice.filters.selectmeaning')}
      disabled={disabled}
      data={whatItMeansOptions}
    />
  );
};

export const NextStepsArraySelectComponent: FieldComponent = ({ value, onChange, label, disabled }) => {
  const t = useI18n();
  const arrayValue = Array.isArray(value) ? value : [];

  // Define the enum values based on the SQL schema
  const NextStepsEnum = {
    IMPROVE_GERMAN_B_TWO: 'IMPROVE_GERMAN_B_TWO',
    IMPROVE_GERMAN_B_ONE: 'IMPROVE_GERMAN_B_ONE',
    SUBMIT_APPLICATION_ASSISTANT: 'SUBMIT_APPLICATION_ASSISTANT',
    GET_HELP: 'GET_HELP',
    CONNECT_WITH_EMPLOYERS: 'CONNECT_WITH_EMPLOYERS',
  } as const;

  const nextStepsOptions = Object.values(NextStepsEnum).map(step => ({
    value: step,
    label: step.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, l => l.toUpperCase())
  }));

  return (
    <MultiSelect
      label={label as any}
      placeholder={t('backoffice.filters.selectsteps')}
      value={arrayValue}
      onChange={(val) => onChange(val || [])}
      data={nextStepsOptions}
      disabled={disabled}
    />
  );
};

export const MinimumGermanLevelSelectComponent: FieldComponent = ({ value, onChange, label, disabled }) => {
  const t = useI18n();
  return (
    <EnumSelect
      enumObject={LanguageLevels}
      enumName="LanguageLevel"
      value={value || null}
      onChange={onChange}
      label={label}
      placeholder={t('backoffice.filters.selectlevel')}
      disabled={disabled}
    />
  );
};

// Duration input component that converts text like "1y 5m" to hours
export const DurationInputComponent: FieldComponent = ({ value, onChange, label, placeholder, disabled }) => {
  const t = useI18n();
  const [inputValue, setInputValue] = React.useState('');

  // Convert hours to display format
  const hoursToDisplayFormat = (hours: number): string => {
    if (!hours || hours === 0) return '';

    let remaining = hours;
    const parts = [];

    // Calculate years
    const years = Math.floor(remaining / (365 * 24));
    if (years > 0) {
      parts.push(`${years}y`);
      remaining -= years * 365 * 24;
    }

    // Calculate months
    const months = Math.floor(remaining / (30 * 24));
    if (months > 0) {
      parts.push(`${months}m`);
      remaining -= months * 30 * 24;
    }

    // Calculate days
    const days = Math.floor(remaining / 24);
    if (days > 0) {
      parts.push(`${days}d`);
      remaining -= days * 24;
    }

    // Remaining hours
    if (remaining > 0) {
      parts.push(`${remaining}h`);
    }

    return parts.join(' ') || '0h';
  };

  // Convert display format to hours
  const displayFormatToHours = (input: string): number => {
    if (!input) return 0;

    let totalHours = 0;
    const yearMatch = input.match(/(\d+)y/);
    const monthMatch = input.match(/(\d+)m/);
    const dayMatch = input.match(/(\d+)d/);
    const hourMatch = input.match(/(\d+)h/);

    if (yearMatch) totalHours += parseInt(yearMatch[1]) * 365 * 24;
    if (monthMatch) totalHours += parseInt(monthMatch[1]) * 30 * 24;
    if (dayMatch) totalHours += parseInt(dayMatch[1]) * 24;
    if (hourMatch) totalHours += parseInt(hourMatch[1]);

    return totalHours;
  };

  // Initialize input value from props
  React.useEffect(() => {
    if (value !== undefined && value !== null) {
      setInputValue(hoursToDisplayFormat(value));
    }
  }, [value]);

  const handleInputChange = (newInputValue: string) => {
    setInputValue(newInputValue);
    const hours = displayFormatToHours(newInputValue);
    onChange(hours);
  };

  return (
    <Group gap="xs" align="flex-end">
      <TextInput
        value={inputValue}
        onChange={(e) => handleInputChange(e.target.value)}
        label={label as any}
        placeholder={placeholder || t('backoffice.filters.durationexample')}
        disabled={disabled}
        style={{ flex: 1 }}
      />
      <Text size="xs" c="dimmed" pb="xs">
        {value ? asI18n(`${value} hours`) : asI18n('')}
      </Text>
    </Group>
  );
};

// Field metadata mapping using enum values directly
export const FIELD_METADATA: Record<string, Record<string, FieldComponent>> = {
  // Nursing License fields
  [CandidateDocumentTypes.LICENSE]: {
    licenseNumber: TextInputComponent,
    licenseType: TextInputComponent,
    issuingAuthority: TextInputComponent,
    issueDate: DateInputComponent,
    expiryDate: DateInputComponent,
    status: TextInputComponent,
  },

  // Training Certificate fields
  [CandidateDocumentTypes.EDUCATION]: {
    institution: TextInputComponent,
    program: TextInputComponent,
    country: TextInputComponent,
    completionDate: DateInputComponent,
    nursingRelatedDegree: BooleanSelectComponent,
    accreditedUniversity: BooleanSelectComponent,
    accreditedStudyProgram: BooleanSelectComponent,
    hasTheory: BooleanSelectComponent,
    hasPractice: BooleanSelectComponent,
    durationHours: DurationInputComponent,
    isNursingFocus: BooleanSelectComponent,
  },

  // German Language Certificate fields
  [CandidateDocumentTypes.LANGUAGE]: {
    level: LanguageLevelSelectComponent,
    issuingBody: TextInputComponent,
    issueDate: DateInputComponent,
    certifiedSkills: StringArrayComponent,
  },

  // Work Experience fields
  [CandidateDocumentTypes.WORK_EXPERIENCE]: {
    employer: TextInputComponent,
    position: TextInputComponent,
    department: TextInputComponent,
    startDate: DateInputComponent,
    endDate: DateInputComponent,
    durationMonths: NumberInputComponent,
    isFullTime: BooleanSelectComponent,
    duties: StringArrayComponent,
  },

  // Nursing Qualification Rule fields
  'nursing_qualification_rule': {
  },
};

export function getFieldComponent(documentType: string, fieldName: string): FieldComponent {
  return FIELD_METADATA[documentType]?.[fieldName] || TextInputComponent;
}
