'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 {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle
} from '@/components/ui/sheet';
import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea';
import { formatDateTime } from '@/lib/date-format';
import {
  activateDocumentLibraryVersionMutation,
  archiveDocumentLibraryVersionMutation,
  createDocumentLibraryMutation,
  deleteDraftDocumentLibraryVersionMutation,
  publishDocumentLibraryVersionMutation,
  updateDocumentLibraryMutation,
  uploadDocumentLibraryVersionMutation
} from '../mutations';
import {
  documentLibrariesQueryOptions,
  documentLibraryByIdOptions
} from '../queries';
import {
  getActiveDocumentLibraryDownloadUrl,
  getActiveDocumentLibraryPreviewUrl,
  getDocumentLibraryDownloadUrl,
  getDocumentLibraryPreviewUrl
} from '../service';
import {
  DOCUMENT_LIBRARY_BRANDS,
  DOCUMENT_LIBRARY_LANGUAGES,
  DOCUMENT_LIBRARY_PRODUCT_TYPES,
  DOCUMENT_LIBRARY_TYPES,
  type DocumentLibraryDetail,
  type DocumentLibraryListItem,
  type DocumentLibraryMutationPayload,
  type DocumentLibraryVersionRecord
} from '../types';

type LibraryFormState = {
  code: string;
  name: string;
  documentType: DocumentLibraryMutationPayload['documentType'];
  description: string;
  brand: DocumentLibraryMutationPayload['brand'];
  language: DocumentLibraryMutationPayload['language'];
  productType: DocumentLibraryMutationPayload['productType'];
  isActive: boolean;
};

type VersionUploadState = {
  version: string;
  file: File | null;
};

function toLibraryState(library?: Partial<DocumentLibraryListItem>): LibraryFormState {
  return {
    code: library?.code ?? '',
    name: library?.name ?? '',
    documentType: (library?.documentType as LibraryFormState['documentType']) ?? 'sla',
    description: library?.description ?? '',
    brand: (library?.brand as LibraryFormState['brand']) ?? 'alla',
    language: (library?.language as LibraryFormState['language']) ?? 'th',
    productType: (library?.productType as LibraryFormState['productType']) ?? 'all',
    isActive: library?.isActive ?? true
  };
}

function buildLibraryPayload(state: LibraryFormState): DocumentLibraryMutationPayload {
  return {
    code: state.code,
    name: state.name,
    documentType: state.documentType,
    description: state.description || null,
    brand: state.brand,
    language: state.language,
    productType: state.productType,
    isActive: state.isActive
  };
}

function openFile(url: string) {
  window.open(url, '_blank', 'noopener,noreferrer');
}

function LibraryDialog({
  open,
  onOpenChange,
  library
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  library?: DocumentLibraryListItem;
}) {
  const [state, setState] = React.useState<LibraryFormState>(toLibraryState(library));
  const createMutation = useMutation({
    ...createDocumentLibraryMutation,
    onSuccess: () => {
      toast.success('Document library item created');
      onOpenChange(false);
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : 'Create failed');
    }
  });
  const updateMutation = useMutation({
    ...updateDocumentLibraryMutation,
    onSuccess: () => {
      toast.success('Document library item updated');
      onOpenChange(false);
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : 'Update failed');
    }
  });

  React.useEffect(() => {
    if (open) {
      setState(toLibraryState(library));
    }
  }, [open, library]);

  async function onSubmit(event: React.FormEvent) {
    event.preventDefault();
    const payload = buildLibraryPayload(state);

    if (library) {
      await updateMutation.mutateAsync({ id: library.id, values: payload });
      return;
    }

    await createMutation.mutateAsync(payload);
  }

  const isPending = createMutation.isPending || updateMutation.isPending;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className='sm:max-w-2xl'>
        <DialogHeader>
          <DialogTitle>{library ? 'Edit Library Item' : 'Create Library Item'}</DialogTitle>
          <DialogDescription>
            Manage reusable static PDF documents before later assembly flows.
          </DialogDescription>
        </DialogHeader>
        <form onSubmit={onSubmit} className='grid gap-4'>
          <div className='grid gap-4 md:grid-cols-2'>
            <Input
              placeholder='Code'
              value={state.code}
              onChange={(event) =>
                setState((current) => ({ ...current, code: event.target.value }))
              }
            />
            <Input
              placeholder='Name'
              value={state.name}
              onChange={(event) =>
                setState((current) => ({ ...current, name: event.target.value }))
              }
            />
          </div>
          <div className='grid gap-4 md:grid-cols-2'>
            <Select
              value={state.documentType}
              onValueChange={(value: LibraryFormState['documentType']) =>
                setState((current) => ({ ...current, documentType: value }))
              }
            >
              <SelectTrigger>
                <SelectValue placeholder='Document type' />
              </SelectTrigger>
              <SelectContent>
                {DOCUMENT_LIBRARY_TYPES.map((type) => (
                  <SelectItem key={type} value={type}>
                    {type}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Select
              value={state.brand}
              onValueChange={(value: LibraryFormState['brand']) =>
                setState((current) => ({ ...current, brand: value }))
              }
            >
              <SelectTrigger>
                <SelectValue placeholder='Brand' />
              </SelectTrigger>
              <SelectContent>
                {DOCUMENT_LIBRARY_BRANDS.map((brand) => (
                  <SelectItem key={brand} value={brand}>
                    {brand}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className='grid gap-4 md:grid-cols-2'>
            <Select
              value={state.language}
              onValueChange={(value: LibraryFormState['language']) =>
                setState((current) => ({ ...current, language: value }))
              }
            >
              <SelectTrigger>
                <SelectValue placeholder='Language' />
              </SelectTrigger>
              <SelectContent>
                {DOCUMENT_LIBRARY_LANGUAGES.map((language) => (
                  <SelectItem key={language} value={language}>
                    {language}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Select
              value={state.productType}
              onValueChange={(value: LibraryFormState['productType']) =>
                setState((current) => ({ ...current, productType: value }))
              }
            >
              <SelectTrigger>
                <SelectValue placeholder='Product type' />
              </SelectTrigger>
              <SelectContent>
                {DOCUMENT_LIBRARY_PRODUCT_TYPES.map((productType) => (
                  <SelectItem key={productType} value={productType}>
                    {productType}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <Textarea
            placeholder='Description'
            value={state.description}
            onChange={(event) =>
              setState((current) => ({ ...current, description: event.target.value }))
            }
          />
          <div className='flex items-center justify-between rounded-lg border px-4 py-3'>
            <div>
              <div className='font-medium'>Active Library</div>
              <div className='text-muted-foreground text-sm'>
                Inactive libraries remain visible for audit and historical traceability.
              </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}>
              {library ? 'Save Changes' : 'Create Library'}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function VersionUploadDialog({
  open,
  onOpenChange,
  libraryId
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  libraryId: string;
}) {
  const [state, setState] = React.useState<VersionUploadState>({ version: '', file: null });
  const uploadMutation = useMutation({
    ...uploadDocumentLibraryVersionMutation,
    onSuccess: () => {
      toast.success('Document version uploaded');
      onOpenChange(false);
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : 'Upload failed');
    }
  });

  React.useEffect(() => {
    if (open) {
      setState({ version: '', file: null });
    }
  }, [open]);

  async function onSubmit(event: React.FormEvent) {
    event.preventDefault();

    if (!state.file) {
      toast.error('Please select a PDF file');
      return;
    }

    await uploadMutation.mutateAsync({
      libraryId,
      values: {
        version: state.version,
        file: state.file
      }
    });
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Upload Version</DialogTitle>
          <DialogDescription>
            Draft versions accept PDF uploads only. Publish and activate are separate actions.
          </DialogDescription>
        </DialogHeader>
        <form onSubmit={onSubmit} className='grid gap-4'>
          <Input
            placeholder='Version'
            value={state.version}
            onChange={(event) =>
              setState((current) => ({ ...current, version: event.target.value }))
            }
          />
          <Input
            type='file'
            accept='application/pdf,.pdf'
            onChange={(event) =>
              setState((current) => ({
                ...current,
                file: event.target.files?.[0] ?? null
              }))
            }
          />
          <DialogFooter>
            <Button type='button' variant='outline' onClick={() => onOpenChange(false)}>
              Cancel
            </Button>
            <Button type='submit' isLoading={uploadMutation.isPending}>
              Upload Version
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function VersionActions({
  libraryId,
  version
}: {
  libraryId: string;
  version: DocumentLibraryVersionRecord;
}) {
  const publishMutation = useMutation({
    ...publishDocumentLibraryVersionMutation,
    onSuccess: () => toast.success('Version published'),
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Publish failed')
  });
  const activateMutation = useMutation({
    ...activateDocumentLibraryVersionMutation,
    onSuccess: () => toast.success('Version activated'),
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Activate failed')
  });
  const archiveMutation = useMutation({
    ...archiveDocumentLibraryVersionMutation,
    onSuccess: () => toast.success('Version archived'),
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Archive failed')
  });
  const deleteMutation = useMutation({
    ...deleteDraftDocumentLibraryVersionMutation,
    onSuccess: () => toast.success('Draft version deleted'),
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Delete failed')
  });

  return (
    <div className='flex flex-wrap gap-2'>
      <Button
        variant='outline'
        size='sm'
        onClick={() => openFile(getDocumentLibraryPreviewUrl(version.id))}
      >
        Preview
      </Button>
      <Button
        variant='outline'
        size='sm'
        onClick={() => openFile(getDocumentLibraryDownloadUrl(version.id))}
      >
        Download
      </Button>
      {version.status === 'draft' ? (
        <Button
          size='sm'
          variant='outline'
          isLoading={publishMutation.isPending}
          onClick={() => publishMutation.mutate({ libraryId, versionId: version.id })}
        >
          Publish
        </Button>
      ) : null}
      {version.status === 'published' ? (
        <Button
          size='sm'
          isLoading={activateMutation.isPending}
          onClick={() => activateMutation.mutate({ libraryId, versionId: version.id })}
        >
          Activate
        </Button>
      ) : null}
      {(version.status === 'draft' || version.status === 'published') && !version.isActive ? (
        <Button
          size='sm'
          variant='outline'
          isLoading={archiveMutation.isPending}
          onClick={() => archiveMutation.mutate({ libraryId, versionId: version.id })}
        >
          Archive
        </Button>
      ) : null}
      {version.status === 'draft' ? (
        <Button
          size='sm'
          variant='outline'
          isLoading={deleteMutation.isPending}
          onClick={() => deleteMutation.mutate({ libraryId, versionId: version.id })}
        >
          Delete Draft
        </Button>
      ) : null}
    </div>
  );
}

function DocumentLibraryDetailSheet({
  libraryId,
  open,
  onOpenChange
}: {
  libraryId: string;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const { data } = useSuspenseQuery(documentLibraryByIdOptions(libraryId));
  const [uploadDialogOpen, setUploadDialogOpen] = React.useState(false);
  const library = data.library;

  return (
    <>
      <Sheet open={open} onOpenChange={onOpenChange}>
        <SheetContent side='right' className='w-full overflow-y-auto sm:max-w-5xl'>
          <SheetHeader>
            <SheetTitle>{library.name}</SheetTitle>
            <SheetDescription>
              {library.code} • {library.documentType} • {library.brand} • {library.language}
            </SheetDescription>
          </SheetHeader>
          <div className='space-y-6 pb-6'>
            <div className='grid gap-4 md:grid-cols-4'>
              <div className='rounded-lg border p-4'>
                <div className='text-muted-foreground text-xs'>Product Type</div>
                <div className='mt-1 text-sm font-medium'>{library.productType}</div>
              </div>
              <div className='rounded-lg border p-4'>
                <div className='text-muted-foreground text-xs'>Versions</div>
                <div className='mt-1 text-sm font-medium'>{library.versions.length}</div>
              </div>
              <div className='rounded-lg border p-4'>
                <div className='text-muted-foreground text-xs'>Updated At</div>
                <div className='mt-1 text-sm font-medium'>{formatDateTime(library.updatedAt)}</div>
              </div>
              <div className='rounded-lg border p-4'>
                <div className='text-muted-foreground text-xs'>Description</div>
                <div className='mt-1 text-sm font-medium'>
                  {library.description || 'No description provided'}
                </div>
              </div>
            </div>

            <div className='flex flex-wrap gap-2'>
              <Button onClick={() => setUploadDialogOpen(true)}>
                <Icons.add className='mr-2 h-4 w-4' />
                Upload Version
              </Button>
              <Button
                variant='outline'
                onClick={() => openFile(getActiveDocumentLibraryPreviewUrl(library.id))}
              >
                Preview Active
              </Button>
              <Button
                variant='outline'
                onClick={() => openFile(getActiveDocumentLibraryDownloadUrl(library.id))}
              >
                Download Active
              </Button>
            </div>

            {library.versions.length === 0 ? (
              <div className='text-muted-foreground rounded-lg border border-dashed p-8 text-center text-sm'>
                No document versions uploaded yet.
              </div>
            ) : (
              <div className='space-y-4'>
                {library.versions.map((version) => (
                  <div key={version.id} className='rounded-xl border p-4'>
                    <div className='flex flex-wrap items-start justify-between gap-4'>
                      <div className='space-y-2'>
                        <div className='flex flex-wrap items-center gap-2'>
                          <div className='text-lg font-semibold'>{version.version}</div>
                          <Badge variant={version.isActive ? 'secondary' : 'outline'}>
                            {version.status}
                          </Badge>
                        </div>
                        <div className='text-muted-foreground text-sm'>
                          {version.fileName} • {version.pageCount} page(s) • {version.fileSize} bytes
                        </div>
                        <div className='text-muted-foreground text-xs'>
                          Created {formatDateTime(version.createdAt)}
                          {version.publishedAt
                            ? ` • Published ${formatDateTime(version.publishedAt)}`
                            : ''}
                          {version.archivedAt
                            ? ` • Archived ${formatDateTime(version.archivedAt)}`
                            : ''}
                        </div>
                      </div>
                      <VersionActions libraryId={library.id} version={version} />
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
        </SheetContent>
      </Sheet>
      <VersionUploadDialog
        open={uploadDialogOpen}
        onOpenChange={setUploadDialogOpen}
        libraryId={library.id}
      />
    </>
  );
}

export function DocumentLibrarySettings() {
  const { data } = useSuspenseQuery(documentLibrariesQueryOptions());
  const [dialogState, setDialogState] = React.useState<{
    open: boolean;
    library?: DocumentLibraryListItem;
  }>({ open: false });
  const [detailState, setDetailState] = React.useState<{
    open: boolean;
    libraryId?: string;
  }>({ open: false });
  const [filters, setFilters] = React.useState({
    documentType: '__all__',
    brand: '__all__',
    language: '__all__',
    productType: '__all__'
  });

  const filteredItems = React.useMemo(() => {
    return data.items.filter((item) => {
      if (filters.documentType !== '__all__' && item.documentType !== filters.documentType) {
        return false;
      }

      if (filters.brand !== '__all__' && item.brand !== filters.brand) {
        return false;
      }

      if (filters.language !== '__all__' && item.language !== filters.language) {
        return false;
      }

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

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

  return (
    <div className='space-y-6'>
      <div className='flex flex-col gap-4 rounded-lg border p-4'>
        <div className='flex flex-wrap items-center justify-between gap-4'>
          <div>
            <div className='font-medium'>Document Library Foundation</div>
            <div className='text-muted-foreground text-sm'>
              Manage reusable PDF documents such as SLA, warranty, datasheet, and profile files.
            </div>
          </div>
          <Button onClick={() => setDialogState({ open: true })}>
            <Icons.add className='mr-2 h-4 w-4' />
            Create Library Item
          </Button>
        </div>
        <div className='grid gap-4 md:grid-cols-4'>
          <Select
            value={filters.documentType}
            onValueChange={(value) =>
              setFilters((current) => ({ ...current, documentType: value }))
            }
          >
            <SelectTrigger>
              <SelectValue placeholder='All types' />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value='__all__'>All types</SelectItem>
              {DOCUMENT_LIBRARY_TYPES.map((type) => (
                <SelectItem key={type} value={type}>
                  {type}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select
            value={filters.brand}
            onValueChange={(value) => setFilters((current) => ({ ...current, brand: value }))}
          >
            <SelectTrigger>
              <SelectValue placeholder='All brands' />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value='__all__'>All brands</SelectItem>
              {DOCUMENT_LIBRARY_BRANDS.map((brand) => (
                <SelectItem key={brand} value={brand}>
                  {brand}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select
            value={filters.language}
            onValueChange={(value) =>
              setFilters((current) => ({ ...current, language: value }))
            }
          >
            <SelectTrigger>
              <SelectValue placeholder='All languages' />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value='__all__'>All languages</SelectItem>
              {DOCUMENT_LIBRARY_LANGUAGES.map((language) => (
                <SelectItem key={language} value={language}>
                  {language}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select
            value={filters.productType}
            onValueChange={(value) =>
              setFilters((current) => ({ ...current, productType: value }))
            }
          >
            <SelectTrigger>
              <SelectValue placeholder='All products' />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value='__all__'>All products</SelectItem>
              {DOCUMENT_LIBRARY_PRODUCT_TYPES.map((productType) => (
                <SelectItem key={productType} value={productType}>
                  {productType}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </div>

      {filteredItems.length === 0 ? (
        <div className='text-muted-foreground rounded-lg border border-dashed p-8 text-center text-sm'>
          No document library items match the current filters.
        </div>
      ) : (
        filteredItems.map((item) => (
          <div key={item.id} className='rounded-xl border p-5'>
            <div className='flex flex-wrap items-start justify-between gap-4'>
              <div className='space-y-1'>
                <div className='text-xl font-semibold'>{item.name}</div>
                <div className='text-muted-foreground text-sm'>
                  {item.code} • {item.documentType} • {item.brand} • {item.language} •{' '}
                  {item.productType}
                </div>
                <div className='text-muted-foreground text-sm'>
                  {item.description || 'No description provided.'}
                </div>
              </div>
              <div className='flex flex-wrap gap-2'>
                <Badge variant={item.isActive ? 'secondary' : 'outline'}>{item.status}</Badge>
                <Badge variant='outline'>Active {item.activeVersion ?? '-'}</Badge>
                <Badge variant='outline'>{item.versionCount} version(s)</Badge>
              </div>
            </div>
            <div className='mt-4 flex flex-wrap gap-2'>
              <Button
                variant='outline'
                onClick={() => setDialogState({ open: true, library: item })}
              >
                Edit Metadata
              </Button>
              <Button
                onClick={() => setDetailState({ open: true, libraryId: item.id })}
              >
                Manage Versions
              </Button>
            </div>
          </div>
        ))
      )}

      <LibraryDialog
        open={dialogState.open}
        onOpenChange={(open) => setDialogState((current) => ({ ...current, open }))}
        library={dialogState.library}
      />

      {detailState.open && detailState.libraryId ? (
        <React.Suspense fallback={null}>
          <DocumentLibraryDetailSheet
            libraryId={detailState.libraryId}
            open={detailState.open}
            onOpenChange={(open) => setDetailState((current) => ({ ...current, open }))}
          />
        </React.Suspense>
      ) : null}
    </div>
  );
}
