'use client';

import * as React from 'react';
import { Calendar } from '@/components/ui/calendar';
import { Icons } from '@/components/icons';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput
} from '@/components/ui/input-group';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Textarea } from '@/components/ui/textarea';
import { cn } from '@/lib/utils';
import { formatCrmDate, formatCrmNumber, sanitizeDecimalInput } from '../shared/formats';

export const CRM_TEXTAREA_SIZE_CLASS = {
  sm: 'min-h-20',
  md: 'min-h-28',
  lg: 'min-h-40'
} as const;

function parseDateValue(value: string | null | undefined) {
  if (!value) {
    return undefined;
  }

  const [year, month, day] = value.split('-').map(Number);

  if (!year || !month || !day) {
    return undefined;
  }

  return new Date(year, month - 1, day);
}

function toDateValue(date?: Date) {
  if (!date) {
    return '';
  }

  return [
    String(date.getFullYear()),
    String(date.getMonth() + 1).padStart(2, '0'),
    String(date.getDate()).padStart(2, '0')
  ].join('-');
}

export function CrmDateInput({
  value,
  onChange,
  placeholder = 'YYYY-MM-DD',
  className,
  allowClear = true
}: {
  value?: string | null;
  onChange: (value: string) => void;
  placeholder?: string;
  className?: string;
  allowClear?: boolean;
}) {
  const selectedDate = parseDateValue(value);

  return (
    <div className={cn('flex items-center gap-2', className)}>
      <Popover>
        <PopoverTrigger asChild>
          <Button
            type='button'
            variant='outline'
            className={cn(
              'min-w-0 flex-1 justify-start overflow-hidden text-left font-normal',
              !value && 'text-muted-foreground'
            )}
          >
            <Icons.calendar className='mr-2 h-4 w-4 shrink-0' />
            <span className='truncate'>{value ? formatCrmDate(value) : placeholder}</span>
          </Button>
        </PopoverTrigger>
        <PopoverContent className='w-auto p-0' align='start'>
          <Calendar
            mode='single'
            selected={selectedDate}
            onSelect={(date) => onChange(toDateValue(date))}
            initialFocus
          />
        </PopoverContent>
      </Popover>
      {allowClear && value ? (
        <Button type='button' variant='outline' size='icon' onClick={() => onChange('')}>
          <Icons.close />
          <span className='sr-only'>Clear date</span>
        </Button>
      ) : null}
    </div>
  );
}

function useFormattedNumericValue(value: string | number | null | undefined, options?: Intl.NumberFormatOptions) {
  const [isFocused, setIsFocused] = React.useState(false);

  const displayValue = React.useMemo(() => {
    if (value === '' || value === null || value === undefined) {
      return '';
    }

    return isFocused ? String(value).replaceAll(',', '') : formatCrmNumber(value, options);
  }, [isFocused, options, value]);

  return {
    displayValue,
    isFocused,
    onFocus: () => setIsFocused(true),
    onBlur: () => setIsFocused(false)
  };
}

export function CrmNumberInput({
  value,
  onChange,
  min,
  max,
  step,
  placeholder,
  className
}: {
  value: string;
  onChange: (value: string) => void;
  min?: number;
  max?: number;
  step?: number | string;
  placeholder?: string;
  className?: string;
}) {
  return (
    <Input
      type='number'
      inputMode='decimal'
      value={value}
      min={min}
      max={max}
      step={step}
      placeholder={placeholder}
      className={cn('w-full', className)}
      onChange={(event) => onChange(event.target.value)}
    />
  );
}

export function CrmCurrencyInput({
  value,
  onChange,
  currencyLabel = 'THB',
  placeholder = '0.00',
  className
}: {
  value: string;
  onChange: (value: string) => void;
  currencyLabel?: string;
  placeholder?: string;
  className?: string;
}) {
  const { displayValue, onBlur, onFocus } = useFormattedNumericValue(value, {
    minimumFractionDigits: value ? 2 : 0,
    maximumFractionDigits: 2
  });

  return (
    <InputGroup className={className}>
      <InputGroupAddon>{currencyLabel}</InputGroupAddon>
      <InputGroupInput
        type='text'
        inputMode='decimal'
        placeholder={placeholder}
        value={displayValue}
        onFocus={onFocus}
        onBlur={onBlur}
        onChange={(event) => onChange(sanitizeDecimalInput(event.target.value))}
      />
    </InputGroup>
  );
}

export function CrmPercentageInput({
  value,
  onChange,
  placeholder = '0',
  className
}: {
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  className?: string;
}) {
  return (
    <InputGroup className={className}>
      <InputGroupInput
        type='number'
        inputMode='decimal'
        min={0}
        max={100}
        step='0.01'
        placeholder={placeholder}
        value={value}
        onChange={(event) => onChange(event.target.value)}
      />
      <InputGroupAddon align='inline-end'>%</InputGroupAddon>
    </InputGroup>
  );
}

export function CrmTextarea({
  size = 'md',
  className,
  ...props
}: React.ComponentProps<typeof Textarea> & {
  size?: keyof typeof CRM_TEXTAREA_SIZE_CLASS;
}) {
  return (
    <Textarea
      className={cn(CRM_TEXTAREA_SIZE_CLASS[size], 'resize-y', className)}
      {...props}
    />
  );
}
