'use client';

import { useEffect, useMemo, useState } from 'react';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea';
import { CRM_MASTER_OPTION_CATEGORIES } from '@/features/foundation/master-options/types';
import type { MasterOptionItem, MasterOptionMutationPayload } from '../api/types';

const EMPTY_METADATA = '{}';

type FormState = {
  category: string;
  code: string;
  label: string;
  value: string;
  parent_id: string;
  sort_order: string;
  is_active: boolean;
  metadata: string;
};

function buildInitialState(option?: MasterOptionItem): FormState {
  return {
    category: option?.category ?? CRM_MASTER_OPTION_CATEGORIES[0] ?? '',
    code: option?.code ?? '',
    label: option?.label ?? '',
    value: option?.value ?? '',
    parent_id: option?.parent_id ?? '__none__',
    sort_order: String(option?.sort_order ?? 0),
    is_active: option?.is_active ?? true,
    metadata: option?.metadata ? JSON.stringify(option.metadata, null, 2) : EMPTY_METADATA
  };
}

export function MasterOptionsFormDialog({
  open,
  onOpenChange,
  onSubmit,
  pending,
  option,
  availableParents
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSubmit: (payload: MasterOptionMutationPayload) => Promise<void>;
  pending: boolean;
  option?: MasterOptionItem;
  availableParents: MasterOptionItem[];
}) {
  const [state, setState] = useState<FormState>(buildInitialState(option));
  const [jsonError, setJsonError] = useState<string | null>(null);

  useEffect(() => {
    if (open) {
      setState(buildInitialState(option));
      setJsonError(null);
    }
  }, [open, option]);

  const parentOptions = useMemo(
    () =>
      availableParents.filter(
        (item) => item.category === state.category && item.id !== option?.id
      ),
    [availableParents, option?.id, state.category]
  );

  async function handleSubmit() {
    try {
      const metadataValue = state.metadata.trim();
      const metadata =
        metadataValue.length > 0 ? (JSON.parse(metadataValue) as Record<string, unknown>) : null;

      setJsonError(null);

      await onSubmit({
        category: state.category,
        code: state.code,
        label: state.label,
        value: state.value || null,
        parent_id: state.parent_id === '__none__' ? null : state.parent_id,
        sort_order: Number(state.sort_order || '0'),
        is_active: state.is_active,
        metadata
      });

      onOpenChange(false);
    } catch (error) {
      if (error instanceof SyntaxError) {
        setJsonError('Metadata must be valid JSON.');
        return;
      }

      throw error;
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className='sm:max-w-2xl'>
        <DialogHeader>
          <DialogTitle>{option ? 'Edit master option' : 'Create master option'}</DialogTitle>
          <DialogDescription>
            Manage organization-scoped lookup values without hardcoding UI labels.
          </DialogDescription>
        </DialogHeader>
        <div className='grid gap-4 py-2'>
          <div className='grid gap-4 md:grid-cols-2'>
            <div className='grid gap-2'>
              <Label htmlFor='master-option-category'>Category</Label>
              <Select
                value={state.category}
                onValueChange={(value) => setState((current) => ({ ...current, category: value }))}
              >
                <SelectTrigger id='master-option-category'>
                  <SelectValue placeholder='Select category' />
                </SelectTrigger>
                <SelectContent>
                  {CRM_MASTER_OPTION_CATEGORIES.map((category) => (
                    <SelectItem key={category} value={category}>
                      {category}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className='grid gap-2'>
              <Label htmlFor='master-option-code'>Code</Label>
              <Input
                id='master-option-code'
                value={state.code}
                onChange={(event) =>
                  setState((current) => ({ ...current, code: event.target.value }))
                }
                placeholder='snake_case_code'
              />
            </div>
          </div>
          <div className='grid gap-4 md:grid-cols-2'>
            <div className='grid gap-2'>
              <Label htmlFor='master-option-label'>Label</Label>
              <Input
                id='master-option-label'
                value={state.label}
                onChange={(event) =>
                  setState((current) => ({ ...current, label: event.target.value }))
                }
                placeholder='Display label'
              />
            </div>
            <div className='grid gap-2'>
              <Label htmlFor='master-option-value'>Value</Label>
              <Input
                id='master-option-value'
                value={state.value}
                onChange={(event) =>
                  setState((current) => ({ ...current, value: event.target.value }))
                }
                placeholder='Optional value'
              />
            </div>
          </div>
          <div className='grid gap-4 md:grid-cols-2'>
            <div className='grid gap-2'>
              <Label htmlFor='master-option-parent'>Parent</Label>
              <Select
                value={state.parent_id}
                onValueChange={(value) =>
                  setState((current) => ({ ...current, parent_id: value }))
                }
              >
                <SelectTrigger id='master-option-parent'>
                  <SelectValue placeholder='No parent' />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value='__none__'>No parent</SelectItem>
                  {parentOptions.map((parent) => (
                    <SelectItem key={parent.id} value={parent.id}>
                      {parent.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className='grid gap-2'>
              <Label htmlFor='master-option-sort-order'>Sort order</Label>
              <Input
                id='master-option-sort-order'
                type='number'
                value={state.sort_order}
                onChange={(event) =>
                  setState((current) => ({ ...current, sort_order: event.target.value }))
                }
              />
            </div>
          </div>
          <div className='flex items-center justify-between rounded-lg border p-3'>
            <div className='space-y-1'>
              <div className='text-sm font-medium'>Active option</div>
              <div className='text-muted-foreground text-xs'>
                Inactive options stay available for admin review but should disappear from normal
                dropdowns.
              </div>
            </div>
            <Switch
              checked={state.is_active}
              onCheckedChange={(checked) =>
                setState((current) => ({ ...current, is_active: checked }))
              }
            />
          </div>
          <div className='grid gap-2'>
            <Label htmlFor='master-option-metadata'>Metadata JSON</Label>
            <Textarea
              id='master-option-metadata'
              value={state.metadata}
              onChange={(event) =>
                setState((current) => ({ ...current, metadata: event.target.value }))
              }
              className='min-h-40 font-mono text-xs'
            />
            {jsonError ? <p className='text-destructive text-xs'>{jsonError}</p> : null}
          </div>
        </div>
        <DialogFooter>
          <Button variant='outline' onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button isLoading={pending} onClick={() => void handleSubmit()}>
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
