'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 { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
  activateDocumentTemplateVersionMutation,
  archiveDocumentTemplateVersionMutation,
  compareDocumentTemplateVersionsMutation,
  duplicateDocumentTemplateVersionMutation,
  previewDocumentTemplateVersionMutation,
  publishDocumentTemplateVersionMutation,
  rollbackDocumentTemplateVersionMutation,
  validateDocumentTemplateVersionMutation,
} from '../mutations';
import { documentTemplateVersionManagementQueryOptions } from '../queries';
import type {
  DocumentTemplateVersionAuditSummary,
  DocumentTemplateVersionCompareResponse,
  DocumentTemplateVersionDetail,
  DocumentTemplateVersionValidationSummary,
  DocumentTemplateVersionVisualSummary,
} from '../types';

function getStatusBadgeVariant(status: 'PASS' | 'WARNING' | 'FAIL' | 'NOT_RUN') {
  if (status === 'PASS') {
    return 'secondary' as const;
  }

  if (status === 'FAIL') {
    return 'destructive' as const;
  }

  return 'outline' as const;
}

function getLifecycleBadgeVariant(
  status: DocumentTemplateVersionDetail['lifecycleStatus'],
) {
  if (status === 'active') {
    return 'secondary' as const;
  }

  if (status === 'archived') {
    return 'outline' as const;
  }

  return 'default' as const;
}

function SummaryCard({
  label,
  value,
}: {
  label: string;
  value: React.ReactNode;
}) {
  return (
    <div className='rounded-lg bg-muted/40 p-3'>
      <div className='text-muted-foreground text-xs'>{label}</div>
      <div className='mt-1 text-sm font-medium break-words'>{value}</div>
    </div>
  );
}

function StringList({
  title,
  items,
}: {
  title: string;
  items: string[];
}) {
  if (!items.length) {
    return null;
  }

  return (
    <div className='space-y-2 rounded-lg border p-3'>
      <div className='text-sm font-medium'>{title}</div>
      <div className='space-y-1 text-sm'>
        {items.map((item) => (
          <div key={item} className='text-muted-foreground break-all'>
            {item}
          </div>
        ))}
      </div>
    </div>
  );
}

function ValidationIssues({
  validation,
}: {
  validation: DocumentTemplateVersionValidationSummary | null | undefined;
}) {
  if (!validation?.issues.length) {
    return null;
  }

  return (
    <div className='space-y-2 rounded-lg border p-3'>
      <div className='text-sm font-medium'>Template Health Issues</div>
      <div className='space-y-2'>
        {validation.issues.map((issue) => (
          <div
            key={`${issue.code}-${issue.location}-${issue.message}`}
            className='rounded-md bg-muted/40 p-3 text-sm'
          >
            <div className='flex flex-wrap items-center gap-2'>
              <Badge variant={issue.severity === 'error' ? 'destructive' : 'outline'}>
                {issue.severity}
              </Badge>
              <span className='font-medium'>{issue.code}</span>
              <span className='text-muted-foreground'>{issue.location}</span>
            </div>
            <div className='mt-1'>{issue.message}</div>
            {issue.suggestedFix ? (
              <div className='text-muted-foreground mt-1'>{issue.suggestedFix}</div>
            ) : null}
          </div>
        ))}
      </div>
    </div>
  );
}

function AuditSummary({
  audit,
  visual,
}: {
  audit: DocumentTemplateVersionAuditSummary | null;
  visual: DocumentTemplateVersionVisualSummary | null | undefined;
}) {
  if (!audit) {
    return (
      <div className='text-muted-foreground rounded-lg border border-dashed p-4 text-sm'>
        No audit summary available.
      </div>
    );
  }

  return (
    <div className='grid gap-3 sm:grid-cols-2 xl:grid-cols-4'>
      <SummaryCard
        label='Audit'
        value={<Badge variant={getStatusBadgeVariant(audit.status)}>{audit.status}</Badge>}
      />
      <SummaryCard
        label='Visual Regression'
        value={
          <Badge variant={getStatusBadgeVariant(audit.visualRegressionStatus)}>
            {audit.visualRegressionStatus}
          </Badge>
        }
      />
      <SummaryCard label='Audited At' value={audit.auditedAt ?? 'Not available'} />
      <SummaryCard label='Runtime Version' value={audit.runtimeVersion ?? 'Not set'} />
      <SummaryCard label='Visual Generated' value={visual?.generatedAt ?? 'Not run'} />
      <SummaryCard label='Changed Pages' value={visual?.changedPages ?? 0} />
      <SummaryCard label='Layout Differences' value={visual?.layoutDifferences ?? 0} />
      <SummaryCard label='Visual Status' value={visual?.status ?? 'NOT_RUN'} />
    </div>
  );
}

function CompareDialog({
  open,
  onOpenChange,
  templateId,
  currentVersion,
  versions,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  templateId: string;
  currentVersion: DocumentTemplateVersionDetail;
  versions: DocumentTemplateVersionDetail[];
}) {
  const [rightVersionId, setRightVersionId] = React.useState(
    versions.find((item) => item.id !== currentVersion.id)?.id ?? currentVersion.id,
  );
  const [comparison, setComparison] = React.useState<
    DocumentTemplateVersionCompareResponse['comparison'] | null
  >(null);

  const compareMutation = useMutation({
    ...compareDocumentTemplateVersionsMutation,
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Compare failed'),
  });

  React.useEffect(() => {
    if (open) {
      setComparison(null);
      setRightVersionId(
        versions.find((item) => item.id !== currentVersion.id)?.id ?? currentVersion.id,
      );
    }
  }, [currentVersion.id, open, versions]);

  async function handleCompare() {
    const result = await compareMutation.mutateAsync({
      templateId,
      leftVersionId: currentVersion.id,
      rightVersionId,
    });
    setComparison(result.comparison);
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className='max-h-[85vh] overflow-y-auto sm:max-w-4xl'>
        <DialogHeader>
          <DialogTitle>Compare Versions</DialogTitle>
          <DialogDescription>
            Review metadata, placeholders, mappings, schema fields, and health state
            without opening raw JSON manually.
          </DialogDescription>
        </DialogHeader>

        <div className='grid gap-4 md:grid-cols-2'>
          <div className='space-y-2'>
            <div className='text-sm font-medium'>Base Version</div>
            <div className='rounded-lg border px-3 py-2 text-sm'>{currentVersion.version}</div>
          </div>
          <div className='space-y-2'>
            <div className='text-sm font-medium'>Compare With</div>
            <select
              className='flex h-10 w-full rounded-md border bg-background px-3 py-2 text-sm'
              value={rightVersionId}
              onChange={(event) => setRightVersionId(event.target.value)}
            >
              {versions
                .filter((item) => item.id !== currentVersion.id)
                .map((version) => (
                  <option key={version.id} value={version.id}>
                    {version.version}
                  </option>
                ))}
            </select>
          </div>
        </div>

        {comparison ? (
          <Tabs defaultValue='metadata' className='space-y-4'>
            <TabsList className='flex flex-wrap'>
              <TabsTrigger value='metadata'>Metadata</TabsTrigger>
              <TabsTrigger value='placeholders'>Placeholders</TabsTrigger>
              <TabsTrigger value='mappings'>Mappings</TabsTrigger>
              <TabsTrigger value='schema'>Schema</TabsTrigger>
              <TabsTrigger value='health'>Health</TabsTrigger>
            </TabsList>

            <TabsContent value='metadata' className='space-y-3'>
              {comparison.metadataChanges.length ? (
                comparison.metadataChanges.map((change) => (
                  <div key={change.field} className='rounded-lg border p-3 text-sm'>
                    <div className='font-medium'>{change.field}</div>
                    <div className='text-muted-foreground mt-1'>
                      Left: {String(change.left ?? 'null')}
                    </div>
                    <div className='text-muted-foreground'>
                      Right: {String(change.right ?? 'null')}
                    </div>
                  </div>
                ))
              ) : (
                <div className='text-muted-foreground rounded-lg border border-dashed p-4 text-sm'>
                  No metadata differences detected.
                </div>
              )}
            </TabsContent>

            <TabsContent value='placeholders' className='space-y-3'>
              <StringList
                title='Only In Base Version'
                items={comparison.placeholderOnlyLeft}
              />
              <StringList
                title='Only In Compared Version'
                items={comparison.placeholderOnlyRight}
              />
              {!comparison.placeholderOnlyLeft.length &&
              !comparison.placeholderOnlyRight.length ? (
                <div className='text-muted-foreground rounded-lg border border-dashed p-4 text-sm'>
                  Placeholder sets are identical.
                </div>
              ) : null}
            </TabsContent>

            <TabsContent value='mappings' className='space-y-3'>
              {comparison.mappingDifferences.length ? (
                comparison.mappingDifferences.map((difference) => (
                  <div
                    key={`${difference.placeholderKey}-${difference.difference}`}
                    className='rounded-lg border p-3 text-sm'
                  >
                    <div className='font-medium'>{difference.placeholderKey}</div>
                    <div className='text-muted-foreground mt-1'>
                      {difference.difference}
                    </div>
                  </div>
                ))
              ) : (
                <div className='text-muted-foreground rounded-lg border border-dashed p-4 text-sm'>
                  No mapping differences detected.
                </div>
              )}
            </TabsContent>

            <TabsContent value='schema' className='space-y-3'>
              <StringList
                title='Added Fields'
                items={comparison.fieldSchemaChanges.addedFields}
              />
              <StringList
                title='Removed Fields'
                items={comparison.fieldSchemaChanges.removedFields}
              />
              {comparison.fieldSchemaChanges.changedFields.length ? (
                <div className='space-y-2 rounded-lg border p-3'>
                  <div className='text-sm font-medium'>Changed Field Types</div>
                  {comparison.fieldSchemaChanges.changedFields.map((item) => (
                    <div key={item.field} className='text-muted-foreground text-sm'>
                      {item.field}: {item.difference}
                    </div>
                  ))}
                </div>
              ) : null}
              {comparison.jsonDiff.length ? (
                <div className='space-y-2 rounded-lg border p-3'>
                  <div className='text-sm font-medium'>JSON Differences</div>
                  {comparison.jsonDiff.map((item) => (
                    <div key={item.path} className='text-muted-foreground text-sm'>
                      {item.path}: {String(item.left ?? 'null')} {'->'}{' '}
                      {String(item.right ?? 'null')}
                    </div>
                  ))}
                </div>
              ) : null}
            </TabsContent>

            <TabsContent value='health' className='space-y-3'>
              <div className='grid gap-3 md:grid-cols-2'>
                <SummaryCard
                  label='Base Validation'
                  value={comparison.leftValidation.status}
                />
                <SummaryCard
                  label='Compared Validation'
                  value={comparison.rightValidation.status}
                />
              </div>
              <ValidationIssues validation={comparison.leftValidation} />
              <ValidationIssues validation={comparison.rightValidation} />
            </TabsContent>
          </Tabs>
        ) : null}

        <DialogFooter>
          <Button variant='outline' onClick={() => onOpenChange(false)}>
            Close
          </Button>
          <Button
            onClick={handleCompare}
            isLoading={compareMutation.isPending}
            disabled={!rightVersionId || rightVersionId === currentVersion.id}
          >
            Compare
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

export function TemplateVersionManagementPanel({
  templateId,
  version,
  versions,
}: {
  templateId: string;
  version: DocumentTemplateVersionDetail;
  versions: DocumentTemplateVersionDetail[];
}) {
  const { data } = useSuspenseQuery(
    documentTemplateVersionManagementQueryOptions(version.id),
  );
  const managedVersion = data.version;
  const [compareOpen, setCompareOpen] = React.useState(false);

  const validateMutation = useMutation({
    ...validateDocumentTemplateVersionMutation,
    onSuccess: (result) => toast.success(`Validation: ${result.validation.status}`),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Validate failed'),
  });
  const publishMutation = useMutation({
    ...publishDocumentTemplateVersionMutation,
    onSuccess: () => toast.success('Version published'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Publish failed'),
  });
  const activateMutation = useMutation({
    ...activateDocumentTemplateVersionMutation,
    onSuccess: () => toast.success('Version activated'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Activate failed'),
  });
  const rollbackMutation = useMutation({
    ...rollbackDocumentTemplateVersionMutation,
    onSuccess: () => toast.success('Rollback completed'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Rollback failed'),
  });
  const archiveMutation = useMutation({
    ...archiveDocumentTemplateVersionMutation,
    onSuccess: () => toast.success('Version archived'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Archive failed'),
  });
  const duplicateMutation = useMutation({
    ...duplicateDocumentTemplateVersionMutation,
    onSuccess: () => toast.success('Draft duplicate created'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Duplicate failed'),
  });
  const previewMutation = useMutation({
    ...previewDocumentTemplateVersionMutation,
    onSuccess: (result) => {
      const url = `data:${result.preview.contentType};base64,${result.preview.base64}`;
      window.open(url, '_blank', 'noopener,noreferrer');
      toast.success(`Preview ready (${result.preview.pageCount} pages)`);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Preview failed'),
  });

  const validation = managedVersion.validationSummary ?? null;
  const audit = managedVersion.auditSummary ?? null;
  const visual = managedVersion.visualSummary ?? null;

  return (
    <>
      <div className='space-y-4 rounded-lg border p-4'>
        <div className='flex flex-wrap items-start justify-between gap-3'>
          <div className='space-y-2'>
            <div className='font-medium'>Version Lifecycle Management</div>
            <div className='flex flex-wrap gap-2'>
              <Badge variant={getLifecycleBadgeVariant(managedVersion.lifecycleStatus)}>
                {managedVersion.lifecycleStatus ?? 'draft'}
              </Badge>
              <Badge variant={managedVersion.isActive ? 'secondary' : 'outline'}>
                {managedVersion.isActive ? 'Active Runtime' : 'Inactive Runtime'}
              </Badge>
              {validation ? (
                <Badge variant={getStatusBadgeVariant(validation.status)}>
                  Validation {validation.status}
                </Badge>
              ) : null}
            </div>
          </div>

          <div className='flex flex-wrap gap-2'>
            <Button
              variant='outline'
              onClick={() => previewMutation.mutate(version.id)}
              isLoading={previewMutation.isPending}
            >
              <Icons.post className='mr-2 h-4 w-4' />
              Preview
            </Button>
            <Button
              variant='outline'
              onClick={() =>
                duplicateMutation.mutate({ templateId, versionId: version.id })
              }
              isLoading={duplicateMutation.isPending}
              disabled={managedVersion.lifecycleStatus === 'archived'}
            >
              <Icons.add className='mr-2 h-4 w-4' />
              Duplicate as Draft
            </Button>
            <Button variant='outline' onClick={() => setCompareOpen(true)}>
              <Icons.share className='mr-2 h-4 w-4' />
              Compare
            </Button>
            <Button
              variant='outline'
              onClick={() => validateMutation.mutate(version.id)}
              isLoading={validateMutation.isPending}
            >
              Validate
            </Button>
            <Button
              variant='outline'
              onClick={() => publishMutation.mutate({ templateId, versionId: version.id })}
              isLoading={publishMutation.isPending}
            >
              Publish
            </Button>
            <Button
              onClick={() => activateMutation.mutate({ templateId, versionId: version.id })}
              isLoading={activateMutation.isPending}
            >
              Activate
            </Button>
            <Button
              variant='outline'
              onClick={() => rollbackMutation.mutate({ templateId, versionId: version.id })}
              isLoading={rollbackMutation.isPending}
            >
              Rollback
            </Button>
            <Button
              variant='outline'
              onClick={() => archiveMutation.mutate({ templateId, versionId: version.id })}
              isLoading={archiveMutation.isPending}
            >
              Archive
            </Button>
          </div>
        </div>

        <div className='grid gap-3 sm:grid-cols-2 xl:grid-cols-4'>
          <SummaryCard
            label='Runtime Version'
            value={managedVersion.runtimeVersion ?? 'Not set'}
          />
          <SummaryCard
            label='Template Variant'
            value={managedVersion.templateVariant ?? 'Not set'}
          />
          <SummaryCard label='Brand' value={managedVersion.brand ?? 'Not set'} />
          <SummaryCard
            label='Published At'
            value={managedVersion.publishedAt ?? 'Not published'}
          />
          <SummaryCard
            label='Activated At'
            value={managedVersion.activatedAt ?? 'Not activated'}
          />
          <SummaryCard
            label='Archived At'
            value={managedVersion.archivedAt ?? 'Not archived'}
          />
          <SummaryCard
            label='Previous Version'
            value={managedVersion.previousVersionId ?? 'None'}
          />
          <SummaryCard
            label='Next Version'
            value={managedVersion.nextVersionId ?? 'None'}
          />
        </div>

        <div className='space-y-3'>
          <div className='font-medium'>Validation Summary</div>
          {validation ? (
            <div className='space-y-3'>
              <div className='grid gap-3 sm:grid-cols-2 xl:grid-cols-4'>
                <SummaryCard
                  label='Validation Status'
                  value={<Badge variant={getStatusBadgeVariant(validation.status)}>{validation.status}</Badge>}
                />
                <SummaryCard
                  label='Validated At'
                  value={validation.validatedAt ?? 'Not validated'}
                />
                <SummaryCard
                  label='Health Status'
                  value={validation.healthStatus}
                />
                <SummaryCard
                  label='Suggested Next Step'
                  value={validation.suggestedNextStep ?? '-'}
                />
              </div>

              <StringList
                title='Required Fields Missing'
                items={validation.requiredFieldsMissing}
              />
              <StringList title='Duplicate Fields' items={validation.duplicateFields} />
              <StringList title='Orphan Mappings' items={validation.orphanMappings} />
              <StringList
                title='Unmapped Placeholders'
                items={validation.unmappedPlaceholders}
              />
              <StringList
                title='Unsupported Schema Types'
                items={validation.unsupportedSchemaTypes}
              />
              <StringList
                title='Section Marker Issues'
                items={validation.sectionMarkerIssues}
              />
              <ValidationIssues validation={validation} />
            </div>
          ) : (
            <div className='text-muted-foreground rounded-lg border border-dashed p-4 text-sm'>
              Validation has not been run for this version yet.
            </div>
          )}
        </div>

        <div className='space-y-3'>
          <div className='font-medium'>Audit Summary</div>
          <AuditSummary audit={audit} visual={visual} />
        </div>
      </div>

      <CompareDialog
        open={compareOpen}
        onOpenChange={setCompareOpen}
        templateId={templateId}
        currentVersion={version}
        versions={versions}
      />
    </>
  );
}
