'use client';

import * as React from 'react';
import { useMutation, useSuspenseQuery } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Icons } from '@/components/icons';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { formatDateTime } from '@/lib/date-format';
import type { FoundationBranch } from '@/features/foundation/branch-scope/types';
import {
  DOCUMENT_SEQUENCE_DEFAULT_FORMAT,
  DOCUMENT_SEQUENCE_DEFAULT_RESET_POLICY,
  DOCUMENT_SEQUENCE_GENERIC_PRODUCT_TYPE
} from '../config';
import {
  createDocumentSequenceMutation,
  deleteDocumentSequenceMutation,
  resetDocumentSequenceMutation,
  updateDocumentSequenceMutation
} from '../mutations';
import { documentSequencesQueryOptions } from '../queries';
import type {
  DocumentSequenceBranchOption,
  DocumentSequenceListItem,
  DocumentSequenceMutationPayload,
  DocumentSequenceProductTypeOption
} from '../types';

type SequenceState = {
  documentType: string;
  productType: string;
  prefix: string;
  period: string;
  branchId: string;
  currentNumber: string;
  paddingLength: string;
  format: string;
  resetPolicy: string;
  isActive: boolean;
};

type SequenceFilters = {
  branchId: string;
  productType: string;
  documentType: string;
  period: string;
  prefix: string;
};

function toBranchOptions(branches: FoundationBranch[]): DocumentSequenceBranchOption[] {
  return branches.map((branch) => ({
    id: branch.id,
    code: branch.code,
    name: branch.name,
    displayName: `${branch.code.toUpperCase()} - ${branch.name}`
  }));
}

function toState(sequence?: DocumentSequenceListItem): SequenceState {
  return {
    documentType: sequence?.documentType ?? 'quotation',
    productType: sequence?.productType ?? 'crane',
    prefix: sequence?.prefix ?? '',
    period: sequence?.period ?? '',
    branchId: sequence?.branchId ?? '__all__',
    currentNumber: String(sequence?.currentNumber ?? 0),
    paddingLength: String(sequence?.paddingLength ?? 3),
    format: sequence?.format ?? DOCUMENT_SEQUENCE_DEFAULT_FORMAT,
    resetPolicy: sequence?.resetPolicy ?? DOCUMENT_SEQUENCE_DEFAULT_RESET_POLICY,
    isActive: sequence?.isActive ?? true
  };
}

function buildPayload(state: SequenceState): DocumentSequenceMutationPayload {
  return {
    documentType: state.documentType.trim(),
    productType: state.productType,
    prefix: state.prefix.trim(),
    period: state.period.trim(),
    branchId: state.branchId === '__all__' ? null : state.branchId,
    currentNumber: Number(state.currentNumber),
    paddingLength: Number(state.paddingLength),
    format: state.format.trim(),
    resetPolicy: state.resetPolicy.trim(),
    isActive: state.isActive
  };
}

function SequenceDialog({
  open,
  onOpenChange,
  sequence,
  branches,
  productTypes
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  sequence?: DocumentSequenceListItem;
  branches: DocumentSequenceBranchOption[];
  productTypes: DocumentSequenceProductTypeOption[];
}) {
  const [state, setState] = React.useState<SequenceState>(() => toState(sequence));

  React.useEffect(() => {
    setState(toState(sequence));
  }, [sequence]);

  const createMutation = useMutation({
    ...createDocumentSequenceMutation,
    onSuccess: () => {
      toast.success('Sequence created');
      onOpenChange(false);
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : 'Unable to save sequence');
    }
  });
  const updateMutation = useMutation({
    ...updateDocumentSequenceMutation,
    onSuccess: () => {
      toast.success('Sequence updated');
      onOpenChange(false);
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : 'Unable to save sequence');
    }
  });
  const isPending = createMutation.isPending || updateMutation.isPending;

  function onSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const payload = buildPayload(state);

    if (sequence) {
      updateMutation.mutate({ id: sequence.id, values: payload });
      return;
    }

    createMutation.mutate(payload);
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className='max-w-2xl'>
        <DialogHeader>
          <DialogTitle>{sequence ? 'Edit Sequence' : 'Create Sequence'}</DialogTitle>
          <DialogDescription>
            Preview never increments the counter. Generation remains server-side only.
          </DialogDescription>
        </DialogHeader>

        <form onSubmit={onSubmit} className='grid gap-4'>
          <div className='grid gap-4 md:grid-cols-2'>
            <Input
              placeholder='Document type'
              value={state.documentType}
              onChange={(event) =>
                setState((current) => ({ ...current, documentType: event.target.value }))
              }
            />
            <Select
              value={state.productType}
              onValueChange={(value) => setState((current) => ({ ...current, productType: value }))}
            >
              <SelectTrigger>
                <SelectValue placeholder='Select product type scope' />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value={DOCUMENT_SEQUENCE_GENERIC_PRODUCT_TYPE}>
                  All Product Types
                </SelectItem>
                {productTypes.map((productType) => (
                  <SelectItem key={productType.code} value={productType.code}>
                    {productType.label}
                    {productType.sequenceCode ? ` (${productType.sequenceCode})` : ''}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className='grid gap-4 md:grid-cols-2'>
            <Input
              placeholder='Prefix'
              value={state.prefix}
              onChange={(event) =>
                setState((current) => ({ ...current, prefix: event.target.value }))
              }
            />
            <Input
              placeholder='Period (YYMM)'
              value={state.period}
              onChange={(event) =>
                setState((current) => ({ ...current, period: event.target.value }))
              }
            />
          </div>

          <div className='grid gap-4 md:grid-cols-3'>
            <Select
              value={state.branchId}
              onValueChange={(value) => setState((current) => ({ ...current, branchId: value }))}
            >
              <SelectTrigger>
                <SelectValue placeholder='Select branch scope' />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value='__all__'>ALL - All Branches</SelectItem>
                {branches.map((branch) => (
                  <SelectItem key={branch.id} value={branch.id}>
                    {branch.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Input
              placeholder='Current number'
              value={state.currentNumber}
              onChange={(event) =>
                setState((current) => ({ ...current, currentNumber: event.target.value }))
              }
            />
            <Input
              placeholder='Padding length'
              value={state.paddingLength}
              onChange={(event) =>
                setState((current) => ({ ...current, paddingLength: event.target.value }))
              }
            />
          </div>

          <div className='grid gap-4 md:grid-cols-2'>
            <Input
              placeholder='Format'
              value={state.format}
              onChange={(event) =>
                setState((current) => ({ ...current, format: event.target.value }))
              }
            />
            <Input
              placeholder='Reset policy'
              value={state.resetPolicy}
              onChange={(event) =>
                setState((current) => ({ ...current, resetPolicy: event.target.value }))
              }
            />
          </div>

          <div className='flex items-center justify-between rounded-lg border px-4 py-3'>
            <div>
              <div className='font-medium'>Active</div>
              <div className='text-muted-foreground text-sm'>
                Inactive sequences stay preserved for legacy numbering history.
              </div>
            </div>
            <Switch
              checked={state.isActive}
              onCheckedChange={(checked) =>
                setState((current) => ({ ...current, isActive: checked }))
              }
            />
          </div>

          <DialogFooter>
            <Button type='button' variant='outline' onClick={() => onOpenChange(false)}>
              Cancel
            </Button>
            <Button type='submit' isLoading={isPending}>
              {sequence ? 'Save Sequence' : 'Create Sequence'}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

export function DocumentSequenceSettings({
  branches,
  productTypes,
  organizationName
}: {
  branches: FoundationBranch[];
  productTypes: DocumentSequenceProductTypeOption[];
  organizationName: string;
}) {
  const { data } = useSuspenseQuery(documentSequencesQueryOptions());
  const [dialogState, setDialogState] = React.useState<{ open: boolean; sequence?: DocumentSequenceListItem }>({
    open: false
  });
  const [filters, setFilters] = React.useState<SequenceFilters>({
    branchId: '__all__',
    productType: '__all__',
    documentType: '',
    period: '',
    prefix: ''
  });

  const branchOptions = React.useMemo(() => toBranchOptions(branches), [branches]);
  const resetMutation = useMutation({
    ...resetDocumentSequenceMutation,
    onSuccess: () => {
      toast.success('Sequence reset');
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : 'Reset failed');
    }
  });
  const deleteMutation = useMutation({
    ...deleteDocumentSequenceMutation,
    onSuccess: () => {
      toast.success('Sequence deleted');
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : 'Delete failed');
    }
  });

  const items = React.useMemo(() => {
    return data.items.filter((sequence) => {
      if (filters.branchId !== '__all__' && (sequence.branchId ?? '__all__') !== filters.branchId) {
        return false;
      }

      if (filters.productType !== '__all__' && sequence.productType !== filters.productType) {
        return false;
      }

      if (
        filters.documentType.trim() &&
        !sequence.documentType.toLowerCase().includes(filters.documentType.trim().toLowerCase())
      ) {
        return false;
      }

      if (filters.period.trim() && sequence.period !== filters.period.trim()) {
        return false;
      }

      if (
        filters.prefix.trim() &&
        !`${sequence.prefix} ${sequence.format}`
          .toLowerCase()
          .includes(filters.prefix.trim().toLowerCase())
      ) {
        return false;
      }

      return true;
    });
  }, [data.items, filters]);

  return (
    <div className='space-y-6'>
      <div className='flex flex-wrap items-center justify-between gap-4 rounded-lg border p-4'>
        <div>
          <div className='font-medium'>Document Sequence Admin</div>
          <div className='text-muted-foreground text-sm'>
            Maintain running numbers by organization, branch, product type, document type, and
            period without rewriting historical codes.
          </div>
        </div>
        <Button onClick={() => setDialogState({ open: true })}>
          <Icons.add className='mr-2 h-4 w-4' />
          Create Sequence
        </Button>
      </div>

      <div className='grid gap-4 md:grid-cols-6'>
        <div className='rounded-lg border p-4'>
          <div className='text-muted-foreground text-xs'>Organization</div>
          <div className='mt-1 text-sm font-medium'>{organizationName}</div>
        </div>
        <Select
          value={filters.branchId}
          onValueChange={(value) => setFilters((current) => ({ ...current, branchId: value }))}
        >
          <SelectTrigger>
            <SelectValue placeholder='Filter branch' />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value='__all__'>All Branches</SelectItem>
            {branchOptions.map((branch) => (
              <SelectItem key={branch.id} value={branch.id}>
                {branch.displayName}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        <Select
          value={filters.productType}
          onValueChange={(value) => setFilters((current) => ({ ...current, productType: value }))}
        >
          <SelectTrigger>
            <SelectValue placeholder='Filter product type' />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value='__all__'>All Product Types</SelectItem>
            {productTypes.map((productType) => (
              <SelectItem key={productType.code} value={productType.code}>
                {productType.label}
              </SelectItem>
            ))}
            <SelectItem value='legacy'>Legacy</SelectItem>
          </SelectContent>
        </Select>
        <Input
          placeholder='Filter document type'
          value={filters.documentType}
          onChange={(event) =>
            setFilters((current) => ({ ...current, documentType: event.target.value }))
          }
        />
        <Input
          placeholder='Filter period (YYMM)'
          value={filters.period}
          onChange={(event) =>
            setFilters((current) => ({ ...current, period: event.target.value }))
          }
        />
        <Input
          placeholder='Filter prefix / format'
          value={filters.prefix}
          onChange={(event) => {
            setFilters((current) => ({
              ...current,
              prefix: event.target.value
            }));
          }}
        />
      </div>

      {items.length === 0 ? (
        <div className='text-muted-foreground rounded-lg border border-dashed p-8 text-center text-sm'>
          No document sequences match the current filters.
        </div>
      ) : (
        items.map((sequence) => (
          <div key={sequence.id} className='rounded-xl border p-5'>
            <div className='flex flex-wrap items-start justify-between gap-4'>
              <div>
                <div className='text-xl font-semibold'>{sequence.documentType}</div>
                <div className='text-muted-foreground text-sm'>
                  {sequence.prefix} {sequence.period} {'\u2022'} {sequence.branchDisplayName}{' '}
                  {'\u2022'} {sequence.productTypeLabel ?? sequence.productType}
                </div>
              </div>
              <div className='flex gap-2'>
                <Badge variant={sequence.isActive ? 'secondary' : 'outline'}>
                  {sequence.isActive ? 'Active' : 'Inactive'}
                </Badge>
                <Badge variant='outline'>Next {sequence.nextPreview}</Badge>
              </div>
            </div>

            <div className='mt-4 grid gap-4 md:grid-cols-4 xl:grid-cols-8'>
              <MetricCard label='Organization' value={sequence.organizationName ?? '-'} />
              <MetricCard label='Branch' value={sequence.branchDisplayName ?? 'All Branches'} />
              <MetricCard
                label='Product Type'
                value={sequence.productTypeLabel ?? sequence.productType}
              />
              <MetricCard label='Period' value={sequence.period} />
              <MetricCard label='Prefix' value={sequence.prefix} />
              <MetricCard label='Format' value={sequence.format} />
              <MetricCard label='Current Number' value={String(sequence.currentNumber)} />
              <MetricCard label='Updated At' value={formatDateTime(sequence.updatedAt)} />
            </div>

            <div className='mt-4 flex flex-wrap gap-2'>
              <Button
                variant='outline'
                size='sm'
                onClick={() => setDialogState({ open: true, sequence })}
              >
                Edit
              </Button>
              <Button
                variant='outline'
                size='sm'
                onClick={() =>
                  resetMutation.mutate({
                    id: sequence.id,
                    values: { currentNumber: 0 }
                  })
                }
                isLoading={resetMutation.isPending}
              >
                Reset
              </Button>
              <Button
                variant='outline'
                size='sm'
                onClick={() => deleteMutation.mutate(sequence.id)}
                isLoading={deleteMutation.isPending}
              >
                Delete
              </Button>
            </div>
          </div>
        ))
      )}

      <SequenceDialog
        open={dialogState.open}
        onOpenChange={(open) => setDialogState((current) => ({ ...current, open }))}
        sequence={dialogState.sequence}
        branches={branchOptions}
        productTypes={productTypes}
      />
    </div>
  );
}

function MetricCard({ label, value }: { label: string; value: string }) {
  return (
    <div className='rounded-lg bg-muted/40 p-4'>
      <div className='text-muted-foreground text-xs'>{label}</div>
      <div className='mt-1 text-sm font-medium'>{value}</div>
    </div>
  );
}
