'use client';

import Link from 'next/link';
import { useMemo, useState } from 'react';
import { useMutation, useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
import { toast } from 'sonner';
import { AlertModal } from '@/components/modal/alert-modal';
import { Icons } from '@/components/icons';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { RecentActivitiesPanel } from '@/features/crm/activities/components/recent-activities-panel';
import { AuditLogTab } from '@/features/crm/components/audit-log-tab';
import { formatDate, formatDateTime } from '@/lib/date-format';
import { formatNumber } from '@/lib/number-format';
import {
  CrmCurrencyInput,
  CrmDateInput,
  CrmNumberInput,
  CrmPercentageInput,
  CrmTextarea
} from '@/features/crm/components/crm-form-controls';
import {
  createQuotationAttachmentMutation,
  createQuotationCustomerMutation,
  createQuotationFollowupMutation,
  generateQuotationCustomerPackageMutation,
  createQuotationItemMutation,
  createQuotationRevisionMutation,
  createQuotationTopicMutation,
  deleteQuotationAttachmentMutation,
  deleteQuotationCustomerMutation,
  deleteQuotationFollowupMutation,
  deleteQuotationItemMutation,
  deleteQuotationTopicMutation,
  updateQuotationAttachmentMutation,
  updateQuotationCustomerMutation,
  updateQuotationFollowupMutation,
  updateQuotationItemMutation,
  updateQuotationTopicMutation
} from '../api/mutations';
import {
  quotationAttachmentsOptions,
  quotationByIdOptions,
  quotationCustomersOptions,
  quotationFollowupsOptions,
  quotationItemsOptions,
  quotationKeys,
  quotationRevisionsOptions,
  quotationTopicsOptions
} from '../api/queries';
import {
  downloadApprovedQuotationPdf,
  downloadQuotationCustomerPackage,
  generateApprovedQuotationPdf
} from '../api/service';
import type {
  QuotationAttachmentMutationPayload,
  QuotationAttachmentRecord,
  QuotationCustomerListItem,
  QuotationCustomerPackageSource,
  QuotationCustomerMutationPayload,
  QuotationFollowupMutationPayload,
  QuotationFollowupRecord,
  QuotationItemMutationPayload,
  QuotationItemRecord,
  QuotationReferenceData,
  QuotationTopicMutationPayload,
  QuotationTopicRecord
} from '../api/types';
import { submitQuotationApprovalMutation } from '@/features/foundation/approval/mutations';
import { quotationDocumentKeys } from '@/features/crm/quotations/document/queries';
import {
  getCustomerPackageRoleLabel,
  getCustomerPackageUiStatus,
  mapCustomerPackageErrorMessage
} from '../customer-package';
import { QuotationDocumentPreview } from './quotation-document-preview';
import { QuotationFormSheet } from './quotation-form-sheet';
import { QuotationApprovalTab } from './quotation-approval-tab';
import { QuotationStatusBadge } from './quotation-status-badge';
import { getQueryClient } from '@/lib/query-client';

function FieldItem({ label, value }: { label: string; value: string | null | undefined }) {
  return (
    <div className='space-y-1'>
      <div className='text-muted-foreground text-xs'>{label}</div>
      <div className='text-sm'>{value ?? '-'}</div>
    </div>
  );
}

function EmptyState({ message }: { message: string }) {
  return (
    <div className='text-muted-foreground rounded-lg border border-dashed p-8 text-center text-sm'>
      {message}
    </div>
  );
}

function downloadBlobFile(blob: Blob, fileName: string) {
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = fileName;
  document.body.append(anchor);
  anchor.click();
  anchor.remove();
  URL.revokeObjectURL(url);
}

function CustomerPackageSourceItem({ item }: { item: QuotationCustomerPackageSource }) {
  return (
    <div className='rounded-lg border p-3'>
      <div className='flex flex-wrap items-center gap-2'>
        <span className='font-medium'>{getCustomerPackageRoleLabel(item.role)}</span>
        <Badge variant='outline'>{item.sourceType === 'generated' ? 'Generated' : 'Library'}</Badge>
      </div>
      <div className='text-muted-foreground mt-2 text-sm'>{item.fileName}</div>
      <div className='text-muted-foreground mt-1 text-xs'>
        {item.pageCount ? `${formatNumber(item.pageCount)} page(s)` : 'Page count unavailable'}
        {item.fileSize ? ` • ${formatNumber(item.fileSize)} bytes` : ''}
        {item.checksum ? ` • ${item.checksum.slice(0, 16)}` : ''}
      </div>
    </div>
  );
}

function ItemDialog({
  open,
  onOpenChange,
  onSubmit,
  pending,
  referenceData,
  item
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSubmit: (values: QuotationItemMutationPayload) => Promise<void>;
  pending: boolean;
  referenceData: QuotationReferenceData;
  item?: QuotationItemRecord;
}) {
  const [values, setValues] = useState({
    productType: item?.productType ?? referenceData.productTypes[0]?.id ?? '',
    description: item?.description ?? '',
    quantity: String(item?.quantity ?? 1),
    unit: item?.unit ?? '',
    unitPrice: String(item?.unitPrice ?? 0),
    discount: String(item?.discount ?? 0),
    discountType: item?.discountType ?? '',
    taxRate: String(item?.taxRate ?? 0),
    notes: item?.notes ?? ''
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{item ? 'Edit Item' : 'Add Item'}</DialogTitle>
          <DialogDescription>Line items drive quotation totals from the server.</DialogDescription>
        </DialogHeader>
        <div className='grid gap-4'>
          <Select
            value={values.productType}
            onValueChange={(value) => setValues((s) => ({ ...s, productType: value }))}
          >
            <SelectTrigger>
              <SelectValue placeholder='Product type' />
            </SelectTrigger>
            <SelectContent>
              {referenceData.productTypes.map((option) => (
                <SelectItem key={option.id} value={option.id}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Input
            value={values.description}
            onChange={(e) => setValues((s) => ({ ...s, description: e.target.value }))}
            placeholder='Description'
          />
          <div className='grid gap-4 md:grid-cols-2'>
            <CrmNumberInput
              value={values.quantity}
              onChange={(value) => setValues((s) => ({ ...s, quantity: value }))}
              placeholder='Quantity'
            />
            <Select
              value={values.unit || '__none__'}
              onValueChange={(value) =>
                setValues((s) => ({
                  ...s,
                  unit: value === '__none__' ? '' : value
                }))
              }
            >
              <SelectTrigger>
                <SelectValue placeholder='Unit' />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value='__none__'>No unit</SelectItem>
                {referenceData.units.map((option) => (
                  <SelectItem key={option.id} value={option.id}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className='grid gap-4 md:grid-cols-2'>
            <CrmCurrencyInput
              value={values.unitPrice}
              onChange={(value) => setValues((s) => ({ ...s, unitPrice: value }))}
              placeholder='Unit price'
              currencyLabel='THB'
            />
            <CrmCurrencyInput
              value={values.discount}
              onChange={(value) => setValues((s) => ({ ...s, discount: value }))}
              placeholder='Discount'
              currencyLabel='THB'
            />
          </div>
          <div className='grid gap-4 md:grid-cols-2'>
            <Select
              value={values.discountType || '__none__'}
              onValueChange={(value) =>
                setValues((s) => ({
                  ...s,
                  discountType: value === '__none__' ? '' : value
                }))
              }
            >
              <SelectTrigger>
                <SelectValue placeholder='Discount type' />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value='__none__'>No discount type</SelectItem>
                {referenceData.discountTypes.map((option) => (
                  <SelectItem key={option.id} value={option.id}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <CrmPercentageInput
              value={values.taxRate}
              onChange={(value) => setValues((s) => ({ ...s, taxRate: value }))}
              placeholder='Tax rate %'
            />
          </div>
          <CrmTextarea
            value={values.notes}
            onChange={(e) => setValues((s) => ({ ...s, notes: e.target.value }))}
            placeholder='Notes'
            size='md'
          />
        </div>
        <DialogFooter>
          <Button variant='outline' onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            isLoading={pending}
            onClick={async () => {
              await onSubmit({
                productType: values.productType,
                description: values.description,
                quantity: Number(values.quantity),
                unit: values.unit,
                unitPrice: Number(values.unitPrice),
                discount: Number(values.discount),
                discountType: values.discountType || null,
                taxRate: Number(values.taxRate),
                notes: values.notes
              });
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function CustomerDialog({
  open,
  onOpenChange,
  onSubmit,
  pending,
  referenceData,
  relation
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSubmit: (values: QuotationCustomerMutationPayload) => Promise<void>;
  pending: boolean;
  referenceData: QuotationReferenceData;
  relation?: QuotationCustomerListItem;
}) {
  const [customerId, setCustomerId] = useState(
    relation?.customerId ?? referenceData.customers[0]?.id ?? ''
  );
  const [role, setRole] = useState(relation?.role ?? referenceData.projectPartyRoles[0]?.id ?? '');
  const [remark, setRemark] = useState(relation?.remark ?? '');

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{relation ? 'Edit Project Party' : 'Add Project Party'}</DialogTitle>
          <DialogDescription>
            Keep related companies visible with their role in this quotation.
          </DialogDescription>
        </DialogHeader>
        <div className='grid gap-4'>
          <Select value={customerId} onValueChange={setCustomerId}>
            <SelectTrigger>
              <SelectValue placeholder='Customer' />
            </SelectTrigger>
            <SelectContent>
              {referenceData.customers.map((item) => (
                <SelectItem key={item.id} value={item.id}>
                  {item.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select value={role} onValueChange={setRole}>
            <SelectTrigger>
              <SelectValue placeholder='Role' />
            </SelectTrigger>
            <SelectContent>
              {referenceData.projectPartyRoles.map((item) => (
                <SelectItem key={item.id} value={item.id}>
                  {item.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Input
            value={remark}
            onChange={(event) => setRemark(event.target.value)}
            placeholder='Remark'
          />
        </div>
        <DialogFooter>
          <Button variant='outline' onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            isLoading={pending}
            onClick={async () => {
              await onSubmit({ customerId, role, remark: remark || null });
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function TopicDialog({
  open,
  onOpenChange,
  onSubmit,
  pending,
  referenceData,
  topic
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSubmit: (values: QuotationTopicMutationPayload) => Promise<void>;
  pending: boolean;
  referenceData: QuotationReferenceData;
  topic?: QuotationTopicRecord;
}) {
  const [topicType, setTopicType] = useState(
    topic?.topicType ?? referenceData.topicTypes[0]?.id ?? ''
  );
  const [title, setTitle] = useState(topic?.title ?? '');
  const [itemsText, setItemsText] = useState(
    topic?.items.map((item) => item.content).join('\n') ?? ''
  );

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{topic ? 'Edit Topic' : 'Add Topic'}</DialogTitle>
          <DialogDescription>
            Each line becomes a topic item in the generated quotation document.
          </DialogDescription>
        </DialogHeader>
        <div className='grid gap-4'>
          <Select value={topicType} onValueChange={setTopicType}>
            <SelectTrigger>
              <SelectValue placeholder='Topic type' />
            </SelectTrigger>
            <SelectContent>
              {referenceData.topicTypes.map((item) => (
                <SelectItem key={item.id} value={item.id}>
                  {item.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Input
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder='Topic title'
          />
          <CrmTextarea
            value={itemsText}
            onChange={(e) => setItemsText(e.target.value)}
            placeholder='One line per topic item'
            size='lg'
          />
        </div>
        <DialogFooter>
          <Button variant='outline' onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            isLoading={pending}
            onClick={async () => {
              await onSubmit({
                id: topic?.id,
                topicType,
                title,
                items: itemsText
                  .split('\n')
                  .map((item, index) => ({
                    content: item.trim(),
                    sortOrder: index
                  }))
                  .filter((item) => item.content.length > 0)
              });
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function FollowupDialog({
  open,
  onOpenChange,
  onSubmit,
  pending,
  referenceData,
  customerId,
  followup
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSubmit: (values: QuotationFollowupMutationPayload) => Promise<void>;
  pending: boolean;
  referenceData: QuotationReferenceData;
  customerId: string;
  followup?: QuotationFollowupRecord;
}) {
  const contacts = referenceData.contacts.filter((item) => item.customerId === customerId);
  const [values, setValues] = useState({
    followupDate: followup?.followupDate.slice(0, 10) ?? new Date().toISOString().slice(0, 10),
    followupType: followup?.followupType ?? referenceData.followupTypes[0]?.id ?? '',
    contactId: followup?.contactId ?? '',
    outcome: followup?.outcome ?? '',
    notes: followup?.notes ?? '',
    nextFollowupDate: followup?.nextFollowupDate?.slice(0, 10) ?? '',
    nextAction: followup?.nextAction ?? ''
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{followup ? 'Edit Follow-up' : 'Add Follow-up'}</DialogTitle>
          <DialogDescription>
            Keep quotation chasing and commercial communication visible.
          </DialogDescription>
        </DialogHeader>
        <div className='grid gap-4'>
          <CrmDateInput
            value={values.followupDate}
            onChange={(e) => setValues((s) => ({ ...s, followupDate: e }))}
            className='w-full'
          />
          <Select
            value={values.followupType}
            onValueChange={(value) => setValues((s) => ({ ...s, followupType: value }))}
          >
            <SelectTrigger>
              <SelectValue placeholder='Follow-up type' />
            </SelectTrigger>
            <SelectContent>
              {referenceData.followupTypes.map((item) => (
                <SelectItem key={item.id} value={item.id}>
                  {item.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select
            value={values.contactId || '__none__'}
            onValueChange={(value) =>
              setValues((s) => ({
                ...s,
                contactId: value === '__none__' ? '' : value
              }))
            }
          >
            <SelectTrigger>
              <SelectValue placeholder='Contact' />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value='__none__'>No contact</SelectItem>
              {contacts.map((item) => (
                <SelectItem key={item.id} value={item.id}>
                  {item.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Input
            value={values.outcome}
            onChange={(e) => setValues((s) => ({ ...s, outcome: e.target.value }))}
            placeholder='Outcome'
          />
          <CrmDateInput
            value={values.nextFollowupDate}
            onChange={(e) => setValues((s) => ({ ...s, nextFollowupDate: e }))}
            className='w-full'
          />
          <Input
            value={values.nextAction}
            onChange={(e) => setValues((s) => ({ ...s, nextAction: e.target.value }))}
            placeholder='Next action'
          />
          <CrmTextarea
            value={values.notes}
            onChange={(e) => setValues((s) => ({ ...s, notes: e.target.value }))}
            placeholder='Notes'
            size='md'
          />
        </div>
        <DialogFooter>
          <Button variant='outline' onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            isLoading={pending}
            onClick={async () => {
              await onSubmit({
                id: followup?.id,
                followupDate: values.followupDate,
                followupType: values.followupType,
                contactId: values.contactId || null,
                outcome: values.outcome,
                notes: values.notes,
                nextFollowupDate: values.nextFollowupDate || null,
                nextAction: values.nextAction
              });
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function AttachmentDialog({
  open,
  onOpenChange,
  onSubmit,
  pending,
  attachment
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSubmit: (values: QuotationAttachmentMutationPayload) => Promise<void>;
  pending: boolean;
  attachment?: QuotationAttachmentRecord;
}) {
  const [values, setValues] = useState({
    fileName: attachment?.fileName ?? '',
    originalFileName: attachment?.originalFileName ?? '',
    filePath: attachment?.filePath ?? '',
    fileSize: String(attachment?.fileSize ?? 0),
    fileType: attachment?.fileType ?? '',
    description: attachment?.description ?? ''
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>
            {attachment ? 'Edit Attachment Metadata' : 'Add Attachment Metadata'}
          </DialogTitle>
          <DialogDescription>
            Task E stores attachment metadata only, without file upload plumbing.
          </DialogDescription>
        </DialogHeader>
        <div className='grid gap-4'>
          <Input
            value={values.fileName}
            onChange={(e) => setValues((s) => ({ ...s, fileName: e.target.value }))}
            placeholder='Stored file name'
          />
          <Input
            value={values.originalFileName}
            onChange={(e) => setValues((s) => ({ ...s, originalFileName: e.target.value }))}
            placeholder='Original file name'
          />
          <Input
            value={values.filePath}
            onChange={(e) => setValues((s) => ({ ...s, filePath: e.target.value }))}
            placeholder='/crm/quotations/...'
          />
          <div className='grid gap-4 md:grid-cols-2'>
            <Input
              value={values.fileType}
              onChange={(e) => setValues((s) => ({ ...s, fileType: e.target.value }))}
              placeholder='application/pdf'
            />
            <CrmNumberInput
              value={values.fileSize}
              onChange={(value) => setValues((s) => ({ ...s, fileSize: value }))}
              placeholder='File size bytes'
            />
          </div>
          <CrmTextarea
            value={values.description}
            onChange={(e) => setValues((s) => ({ ...s, description: e.target.value }))}
            placeholder='Description'
            size='md'
          />
        </div>
        <DialogFooter>
          <Button variant='outline' onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            isLoading={pending}
            onClick={async () => {
              await onSubmit({
                id: attachment?.id,
                fileName: values.fileName,
                originalFileName: values.originalFileName,
                filePath: values.filePath,
                fileSize: Number(values.fileSize),
                fileType: values.fileType || null,
                description: values.description
              });
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

export function QuotationDetail({
  quotationId,
  referenceData,
  canUpdate,
  canManageItems,
  canManageCustomers,
  canManageTopics,
  canManageFollowups,
  canManageAttachments,
  canCreateRevision,
  canSubmitApproval,
  canApproveApproval,
  canRejectApproval,
  canReturnApproval,
  activeBusinessRole,
  isOrgAdmin,
  currentUserId,
  canPreviewDocument,
  canPreviewPdf,
  canPreviewCustomerPackage,
  canDownloadPdf,
  canGenerateCustomerPackage,
  canDownloadCustomerPackage,
  canGenerateApprovedPdf
}: {
  quotationId: string;
  referenceData: QuotationReferenceData;
  canUpdate: boolean;
  canManageItems: boolean;
  canManageCustomers: boolean;
  canManageTopics: boolean;
  canManageFollowups: boolean;
  canManageAttachments: boolean;
  canCreateRevision: boolean;
  canSubmitApproval: boolean;
  canApproveApproval: boolean;
  canRejectApproval: boolean;
  canReturnApproval: boolean;
  activeBusinessRole: string | null;
  isOrgAdmin: boolean;
  currentUserId: string;
  canPreviewDocument: boolean;
  canPreviewPdf: boolean;
  canPreviewCustomerPackage: boolean;
  canDownloadPdf: boolean;
  canGenerateCustomerPackage: boolean;
  canDownloadCustomerPackage: boolean;
  canGenerateApprovedPdf: boolean;
}) {
  const queryClient = useQueryClient();
  const { data } = useSuspenseQuery(quotationByIdOptions(quotationId));
  const { data: itemsData } = useSuspenseQuery(quotationItemsOptions(quotationId));
  const { data: customersData } = useSuspenseQuery(quotationCustomersOptions(quotationId));
  const { data: topicsData } = useSuspenseQuery(quotationTopicsOptions(quotationId));
  const { data: followupsData } = useSuspenseQuery(quotationFollowupsOptions(quotationId));
  const { data: attachmentsData } = useSuspenseQuery(quotationAttachmentsOptions(quotationId));
  const { data: revisionsData } = useSuspenseQuery(quotationRevisionsOptions(quotationId));
  const quotation = data.quotation;
  const [customerPackageError, setCustomerPackageError] = useState<string | null>(null);
  const [confirmRegenerateOpen, setConfirmRegenerateOpen] = useState(false);
  const customerPackageStatus = getCustomerPackageUiStatus({
    customerPackage: quotation.customerPackage,
    lastErrorMessage: customerPackageError
  });
  const [editOpen, setEditOpen] = useState(false);

  const [itemOpen, setItemOpen] = useState(false);
  const [editingItem, setEditingItem] = useState<QuotationItemRecord | undefined>();
  const [deleteItemId, setDeleteItemId] = useState<string | null>(null);
  const createItem = useMutation({
    ...createQuotationItemMutation,
    onSuccess: () => toast.success('Quotation item saved'),
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Failed to save item')
  });
  const updateItem = useMutation({
    ...updateQuotationItemMutation,
    onSuccess: () => toast.success('Quotation item updated'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to update item')
  });
  const deleteItem = useMutation({
    ...deleteQuotationItemMutation,
    onSuccess: () => {
      toast.success('Quotation item deleted');
      setDeleteItemId(null);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to delete item')
  });

  const [customerOpen, setCustomerOpen] = useState(false);
  const [editingCustomer, setEditingCustomer] = useState<QuotationCustomerListItem | undefined>();
  const [deleteCustomerId, setDeleteCustomerId] = useState<string | null>(null);
  const createCustomer = useMutation({
    ...createQuotationCustomerMutation,
    onSuccess: () => toast.success('Project party saved'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to save project party')
  });
  const updateCustomer = useMutation({
    ...updateQuotationCustomerMutation,
    onSuccess: () => toast.success('Project party updated'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to update project party')
  });
  const deleteCustomer = useMutation({
    ...deleteQuotationCustomerMutation,
    onSuccess: () => {
      toast.success('Project party deleted');
      setDeleteCustomerId(null);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to delete project party')
  });

  const [topicOpen, setTopicOpen] = useState(false);
  const [editingTopic, setEditingTopic] = useState<QuotationTopicRecord | undefined>();
  const [deleteTopicId, setDeleteTopicId] = useState<string | null>(null);
  const createTopic = useMutation({
    ...createQuotationTopicMutation,
    onSuccess: () => toast.success('Topic saved'),
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Failed to save topic')
  });
  const updateTopic = useMutation({
    ...updateQuotationTopicMutation,
    onSuccess: () => toast.success('Topic updated'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to update topic')
  });
  const deleteTopic = useMutation({
    ...deleteQuotationTopicMutation,
    onSuccess: () => {
      toast.success('Topic deleted');
      setDeleteTopicId(null);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to delete topic')
  });

  const [followupOpen, setFollowupOpen] = useState(false);
  const [editingFollowup, setEditingFollowup] = useState<QuotationFollowupRecord | undefined>();
  const [deleteFollowupId, setDeleteFollowupId] = useState<string | null>(null);
  const createFollowup = useMutation({
    ...createQuotationFollowupMutation,
    onSuccess: () => toast.success('Follow-up saved'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to save follow-up')
  });
  const updateFollowup = useMutation({
    ...updateQuotationFollowupMutation,
    onSuccess: () => toast.success('Follow-up updated'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to update follow-up')
  });
  const deleteFollowup = useMutation({
    ...deleteQuotationFollowupMutation,
    onSuccess: () => {
      toast.success('Follow-up deleted');
      setDeleteFollowupId(null);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to delete follow-up')
  });

  const [attachmentOpen, setAttachmentOpen] = useState(false);
  const [editingAttachment, setEditingAttachment] = useState<
    QuotationAttachmentRecord | undefined
  >();
  const [deleteAttachmentId, setDeleteAttachmentId] = useState<string | null>(null);
  const createAttachment = useMutation({
    ...createQuotationAttachmentMutation,
    onSuccess: () => toast.success('Attachment metadata saved'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to save attachment')
  });
  const updateAttachment = useMutation({
    ...updateQuotationAttachmentMutation,
    onSuccess: () => toast.success('Attachment metadata updated'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to update attachment')
  });
  const deleteAttachment = useMutation({
    ...deleteQuotationAttachmentMutation,
    onSuccess: () => {
      toast.success('Attachment metadata deleted');
      setDeleteAttachmentId(null);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to delete attachment')
  });

  const createRevision = useMutation({
    ...createQuotationRevisionMutation,
    onSuccess: () => toast.success('Revision created successfully'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to create revision')
  });
  const submitForApproval = useMutation({
    ...submitQuotationApprovalMutation,
    onSuccess: () => toast.success('Quotation moved to pending approval'),
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to submit for approval')
  });
  const generateCustomerPackage = useMutation({
    ...generateQuotationCustomerPackageMutation,
    onSuccess: () => {
      setCustomerPackageError(null);
      setConfirmRegenerateOpen(false);
      toast.success('Customer package generated successfully');
    },
    onError: (error) => {
      const message = mapCustomerPackageErrorMessage(error instanceof Error ? error.message : null);
      setCustomerPackageError(message);
      setConfirmRegenerateOpen(false);
      toast.error(message);
    }
  });
  const downloadCustomerPackage = useMutation({
    mutationFn: async () => downloadQuotationCustomerPackage(quotationId),
    onSuccess: async ({ blob, fileName }) => {
      setCustomerPackageError(null);
      downloadBlobFile(blob, fileName);
      toast.success('Customer package downloaded successfully');
    },
    onError: (error) => {
      const message = mapCustomerPackageErrorMessage(error instanceof Error ? error.message : null);
      setCustomerPackageError(message);
      toast.error(message);
    }
  });
  const downloadApprovedPdf = useMutation({
    mutationFn: async () => downloadApprovedQuotationPdf(quotationId),
    onSuccess: ({ blob, fileName }) => {
      downloadBlobFile(blob, fileName);
      toast.success('Approved PDF downloaded successfully');
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to download approved PDF')
  });
  const createApprovedPdf = useMutation({
    mutationFn: async () => generateApprovedQuotationPdf(quotationId),
    onSuccess: async ({ blob, fileName }) => {
      await Promise.all([
        queryClient.invalidateQueries({
          queryKey: quotationKeys.detail(quotationId)
        }),
        queryClient.invalidateQueries({ queryKey: quotationKeys.lists() }),
        queryClient.invalidateQueries({
          queryKey: quotationDocumentKeys.data(quotationId)
        }),
        queryClient.invalidateQueries({
          queryKey: quotationDocumentKeys.preview(quotationId)
        })
      ]);
      setCustomerPackageError(null);
      downloadBlobFile(blob, fileName);
      toast.success('Approved PDF generated successfully');
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to generate approved PDF')
  });

  const branchMap = useMemo(
    () => new Map(referenceData.branches.map((item) => [item.id, item.name])),
    [referenceData.branches]
  );
  const customerMap = useMemo(
    () => new Map(referenceData.customers.map((item) => [item.id, item])),
    [referenceData.customers]
  );
  const contactMap = useMemo(
    () => new Map(referenceData.contacts.map((item) => [item.id, item])),
    [referenceData.contacts]
  );
  const statusMap = useMemo(
    () => new Map(referenceData.statuses.map((item) => [item.id, item])),
    [referenceData.statuses]
  );
  const typeMap = useMemo(
    () => new Map(referenceData.quotationTypes.map((item) => [item.id, item])),
    [referenceData.quotationTypes]
  );
  const currencyMap = useMemo(
    () => new Map(referenceData.currencies.map((item) => [item.id, item])),
    [referenceData.currencies]
  );
  const topicTypeMap = useMemo(
    () => new Map(referenceData.topicTypes.map((item) => [item.id, item])),
    [referenceData.topicTypes]
  );
  const followupTypeMap = useMemo(
    () => new Map(referenceData.followupTypes.map((item) => [item.id, item])),
    [referenceData.followupTypes]
  );
  const customer = customerMap.get(quotation.customerId);
  const contact = quotation.contactId ? contactMap.get(quotation.contactId) : null;
  const status = statusMap.get(quotation.status);
  const customerPackage = quotation.customerPackage;
  const hasOfficialDocument = Boolean(quotation.approvedPdfUrl);
  const officialDocumentPreviewHref = `/api/crm/quotations/${quotationId}/approved-pdf`;
  const customerPackageActionLabel = customerPackage ? 'Regenerate Package' : 'Generate Package';
  const customerPackageStatusLabel =
    customerPackageStatus === 'generated'
      ? 'Generated'
      : customerPackageStatus === 'failed'
        ? 'Failed'
        : 'Not Generated';
  const customerPackageStatusDescription =
    customerPackageStatus === 'generated'
      ? 'Customer-facing assembled PDF is ready.'
      : customerPackageStatus === 'failed'
        ? customerPackageError
        : hasOfficialDocument
          ? 'Generate the package from the approved PDF and active document library files.'
          : 'Customer package requires an approved PDF before it can be generated. Generate the official PDF first.';
  const canReviseByStatus = ['accepted', 'rejected', 'sent', 'approved'].includes(
    status?.code ?? ''
  );
  const canSubmitCurrentQuotation =
    canSubmitApproval && ['draft', 'revised'].includes(status?.code ?? '');

  return (
    <div className='space-y-6'>
      <AlertModal
        isOpen={!!deleteItemId}
        onClose={() => setDeleteItemId(null)}
        onConfirm={() => deleteItemId && deleteItem.mutate({ quotationId, itemId: deleteItemId })}
        loading={deleteItem.isPending}
      />
      <AlertModal
        isOpen={!!deleteCustomerId}
        onClose={() => setDeleteCustomerId(null)}
        onConfirm={() =>
          deleteCustomerId && deleteCustomer.mutate({ quotationId, relationId: deleteCustomerId })
        }
        loading={deleteCustomer.isPending}
      />
      <AlertModal
        isOpen={!!deleteTopicId}
        onClose={() => setDeleteTopicId(null)}
        onConfirm={() =>
          deleteTopicId && deleteTopic.mutate({ quotationId, topicId: deleteTopicId })
        }
        loading={deleteTopic.isPending}
      />
      <AlertModal
        isOpen={!!deleteFollowupId}
        onClose={() => setDeleteFollowupId(null)}
        onConfirm={() =>
          deleteFollowupId && deleteFollowup.mutate({ quotationId, followupId: deleteFollowupId })
        }
        loading={deleteFollowup.isPending}
      />
      <AlertModal
        isOpen={!!deleteAttachmentId}
        onClose={() => setDeleteAttachmentId(null)}
        onConfirm={() =>
          deleteAttachmentId &&
          deleteAttachment.mutate({
            quotationId,
            attachmentId: deleteAttachmentId
          })
        }
        loading={deleteAttachment.isPending}
      />

      <ItemDialog
        open={itemOpen}
        onOpenChange={setItemOpen}
        item={editingItem}
        referenceData={referenceData}
        pending={createItem.isPending || updateItem.isPending}
        onSubmit={async (values) => {
          if (editingItem) {
            await updateItem.mutateAsync({
              quotationId,
              itemId: editingItem.id,
              values
            });
            return;
          }

          await createItem.mutateAsync({ quotationId, values });
        }}
      />
      <CustomerDialog
        open={customerOpen}
        onOpenChange={setCustomerOpen}
        relation={editingCustomer}
        referenceData={referenceData}
        pending={createCustomer.isPending || updateCustomer.isPending}
        onSubmit={async (values) => {
          if (editingCustomer) {
            await updateCustomer.mutateAsync({
              quotationId,
              relationId: editingCustomer.id,
              values
            });
            return;
          }

          await createCustomer.mutateAsync({ quotationId, values });
        }}
      />
      <TopicDialog
        open={topicOpen}
        onOpenChange={setTopicOpen}
        topic={editingTopic}
        referenceData={referenceData}
        pending={createTopic.isPending || updateTopic.isPending}
        onSubmit={async (values) => {
          if (editingTopic) {
            await updateTopic.mutateAsync({
              quotationId,
              values: { ...values, id: editingTopic.id }
            });
            return;
          }

          await createTopic.mutateAsync({ quotationId, values });
        }}
      />
      <FollowupDialog
        open={followupOpen}
        onOpenChange={setFollowupOpen}
        followup={editingFollowup}
        customerId={quotation.customerId}
        referenceData={referenceData}
        pending={createFollowup.isPending || updateFollowup.isPending}
        onSubmit={async (values) => {
          if (editingFollowup) {
            await updateFollowup.mutateAsync({
              quotationId,
              values: { ...values, id: editingFollowup.id }
            });
            return;
          }

          await createFollowup.mutateAsync({ quotationId, values });
        }}
      />
      <AttachmentDialog
        open={attachmentOpen}
        onOpenChange={setAttachmentOpen}
        attachment={editingAttachment}
        pending={createAttachment.isPending || updateAttachment.isPending}
        onSubmit={async (values) => {
          if (editingAttachment) {
            await updateAttachment.mutateAsync({
              quotationId,
              values: { ...values, id: editingAttachment.id }
            });
            return;
          }

          await createAttachment.mutateAsync({ quotationId, values });
        }}
      />
      <QuotationFormSheet
        quotation={quotation}
        open={editOpen}
        onOpenChange={setEditOpen}
        referenceData={referenceData}
      />
      <Dialog open={confirmRegenerateOpen} onOpenChange={setConfirmRegenerateOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Regenerate Customer Package?</DialogTitle>
            <DialogDescription>
              A new assembled package artifact will replace the current active package for this
              quotation.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button
              variant='outline'
              onClick={() => setConfirmRegenerateOpen(false)}
              disabled={generateCustomerPackage.isPending}
            >
              Cancel
            </Button>
            <Button
              isLoading={generateCustomerPackage.isPending}
              onClick={() => generateCustomerPackage.mutate({ quotationId })}
            >
              Continue
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <div className='flex flex-col gap-4 rounded-xl border p-5 lg:flex-row lg:items-start lg:justify-between'>
        <div className='space-y-3'>
          <div className='flex items-center gap-2'>
            <Button asChild variant='ghost' size='icon'>
              <Link href='/dashboard/crm/quotations'>
                <Icons.chevronLeft className='h-4 w-4' />
              </Link>
            </Button>
            <span className='text-muted-foreground font-mono text-sm'>{quotation.code}</span>
            <QuotationStatusBadge code={status?.code} label={status?.label ?? 'Unknown'} />
            {quotation.isHotProject ? <Badge>Hot</Badge> : null}
          </div>
          <div>
            <h2 className='text-2xl font-semibold'>
              {quotation.projectName || 'Untitled quotation'}
            </h2>
            <p className='text-muted-foreground text-sm'>
              {customer?.name ?? 'Unknown customer'}
              {contact ? ` - ${contact.name}` : ''}
            </p>
          </div>
        </div>
        <div className='flex flex-wrap gap-2'>
          {canSubmitCurrentQuotation ? (
            <Button
              variant='outline'
              isLoading={submitForApproval.isPending}
              onClick={() => submitForApproval.mutate({ id: quotationId })}
            >
              <Icons.send className='mr-2 h-4 w-4' /> Submit for approval
            </Button>
          ) : null}
          {canCreateRevision && canReviseByStatus ? (
            <Button
              variant='outline'
              isLoading={createRevision.isPending}
              onClick={() => createRevision.mutate({ quotationId })}
            >
              <Icons.add className='mr-2 h-4 w-4' /> Create Revision
            </Button>
          ) : null}
          {canUpdate ? (
            <Button variant='outline' onClick={() => setEditOpen(true)}>
              <Icons.edit className='mr-2 h-4 w-4' /> Edit Quotation
            </Button>
          ) : null}
        </div>
      </div>

      <div className='grid gap-6 lg:grid-cols-3'>
        <div className='space-y-6 lg:col-span-2'>
          <Card>
            <CardContent className='pt-6'>
              {/* <RecentActivitiesPanel
                items={data.recentActivities}
                description="New activity records and legacy quotation follow-ups shown together."
                emptyMessage="No recent activity or quotation follow-up yet."
              /> */}

              <Tabs defaultValue='overview' className='gap-4'>
                <TabsList className='flex flex-wrap'>
                  <TabsTrigger value='overview'>Overview</TabsTrigger>
                  <TabsTrigger value='documents'>Documents</TabsTrigger>
                  <TabsTrigger value='customer-package'>Customer Package</TabsTrigger>
                  <TabsTrigger value='items'>Items</TabsTrigger>
                  <TabsTrigger value='customers'>ผู้เกี่ยวข้องในโครงการ</TabsTrigger>
                  <TabsTrigger value='topics'>Topics</TabsTrigger>
                  <TabsTrigger value='followups'>Follow-ups</TabsTrigger>
                  <TabsTrigger value='attachments'>Attachments</TabsTrigger>
                  <TabsTrigger value='activity'>Audit Log</TabsTrigger>
                  <TabsTrigger value='approval'>Approval</TabsTrigger>
                </TabsList>

                <TabsContent value='overview'>
                  <Card>
                    <CardHeader>
                      <CardTitle>Overview</CardTitle>
                      <CardDescription>
                        Commercial header data and quotation summary.
                      </CardDescription>
                    </CardHeader>
                    <CardContent className='grid gap-4 md:grid-cols-2 xl:grid-cols-4'>
                      <FieldItem label='ลูกค้าผู้รับใบเสนอราคา' value={customer?.name} />
                      <FieldItem label='Contact' value={contact?.name} />
                      <FieldItem
                        label='Branch'
                        value={quotation.branchId ? branchMap.get(quotation.branchId) : null}
                      />
                      <FieldItem label='Type' value={typeMap.get(quotation.quotationType)?.label} />
                      <FieldItem
                        label='Currency'
                        value={currencyMap.get(quotation.currency)?.label}
                      />
                      <FieldItem label='Exchange Rate' value={quotation.exchangeRate.toString()} />
                      <FieldItem
                        label='Quotation Date'
                        value={formatDate(quotation.quotationDate)}
                      />
                      <FieldItem
                        label='Valid Until'
                        value={quotation.validUntil ? formatDate(quotation.validUntil) : null}
                      />
                      <FieldItem label='Subtotal' value={formatNumber(quotation.subtotal)} />
                      <FieldItem label='Tax' value={formatNumber(quotation.taxAmount)} />
                      <FieldItem label='Total' value={formatNumber(quotation.totalAmount)} />
                      <FieldItem
                        label='Chance %'
                        value={
                          quotation.chancePercent !== null ? `${quotation.chancePercent}%` : null
                        }
                      />
                      <div className='md:col-span-2 xl:col-span-4'>
                        <div className='space-y-3'>
                          <div className='text-muted-foreground text-xs'>ผู้เกี่ยวข้องในโครงการ</div>
                          {!customersData.items.length ? (
                            <div className='text-muted-foreground rounded-lg border border-dashed p-4 text-sm'>
                              No project parties have been added yet.
                            </div>
                          ) : (
                            <div className='space-y-3'>
                              {customersData.items.map((item) => (
                                <div key={item.id} className='rounded-lg border p-4 text-sm'>
                                  <div className='font-medium'>{item.customerName}</div>
                                  <div className='text-muted-foreground'>
                                    Role: {item.roleLabel ?? item.roleCode}
                                  </div>
                                  {item.remark ? <div className='mt-1'>{item.remark}</div> : null}
                                </div>
                              ))}
                            </div>
                          )}
                        </div>
                      </div>
                      <div className='md:col-span-2 xl:col-span-4'>
                        <FieldItem
                          label='Project'
                          value={
                            [quotation.projectName, quotation.projectLocation]
                              .filter(Boolean)
                              .join(' - ') || null
                          }
                        />
                      </div>
                      <div className='md:col-span-2 xl:col-span-4'>
                        <FieldItem
                          label='Attention / Reference'
                          value={
                            [quotation.attention, quotation.reference]
                              .filter(Boolean)
                              .join(' - ') || null
                          }
                        />
                      </div>
                      <div className='md:col-span-2 xl:col-span-4'>
                        <FieldItem label='Notes' value={quotation.notes} />
                      </div>
                    </CardContent>
                  </Card>
                </TabsContent>

                <TabsContent value='items'>
                  <Card>
                    <CardHeader className='flex flex-row items-center justify-between'>
                      <div>
                        <CardTitle>Items</CardTitle>
                        <CardDescription>
                          Server-calculated line items and pricing inputs.
                        </CardDescription>
                      </div>
                      {canManageItems ? (
                        <Button
                          onClick={() => {
                            setEditingItem(undefined);
                            setItemOpen(true);
                          }}
                        >
                          <Icons.add className='mr-2 h-4 w-4' /> Add Item
                        </Button>
                      ) : null}
                    </CardHeader>
                    <CardContent className='space-y-3'>
                      {!itemsData.items.length ? (
                        <EmptyState message='No quotation items yet.' />
                      ) : (
                        itemsData.items.map((item) => (
                          <div key={item.id} className='rounded-lg border p-4'>
                            <div className='flex items-start justify-between gap-4'>
                              <div className='space-y-1'>
                                <div className='font-medium'>{item.description}</div>
                                <div className='text-muted-foreground text-sm'>
                                  Qty {item.quantity} {item.unit || ''} x{' '}
                                  {formatNumber(item.unitPrice)}
                                </div>
                                <div className='text-muted-foreground text-xs'>
                                  Total {formatNumber(item.totalPrice)}
                                </div>
                              </div>
                              {canManageItems ? (
                                <div className='flex gap-2'>
                                  <Button
                                    variant='outline'
                                    size='sm'
                                    onClick={() => {
                                      setEditingItem(item);
                                      setItemOpen(true);
                                    }}
                                  >
                                    <Icons.edit className='mr-2 h-4 w-4' /> Edit
                                  </Button>
                                  <Button
                                    variant='outline'
                                    size='sm'
                                    onClick={() => setDeleteItemId(item.id)}
                                  >
                                    <Icons.trash className='mr-2 h-4 w-4' /> Delete
                                  </Button>
                                </div>
                              ) : null}
                            </div>
                          </div>
                        ))
                      )}
                    </CardContent>
                  </Card>
                </TabsContent>

                <TabsContent value='customers'>
                  <Card>
                    <CardHeader className='flex flex-row items-center justify-between'>
                      <div>
                        <CardTitle>ผู้เกี่ยวข้องในโครงการ</CardTitle>
                        <CardDescription>
                          Related companies for this quotation, each with a visible role.
                        </CardDescription>
                      </div>
                      {canManageCustomers ? (
                        <Button
                          onClick={() => {
                            setEditingCustomer(undefined);
                            setCustomerOpen(true);
                          }}
                        >
                          <Icons.add className='mr-2 h-4 w-4' /> Add Party
                        </Button>
                      ) : null}
                    </CardHeader>
                    <CardContent className='space-y-3'>
                      {!customersData.items.length ? (
                        <EmptyState message='No project parties have been added yet.' />
                      ) : (
                        customersData.items.map((item) => (
                          <div
                            key={item.id}
                            className='flex items-center justify-between rounded-lg border p-4'
                          >
                            <div>
                              <div className='font-medium'>{item.customerName}</div>
                              <div className='text-muted-foreground text-sm'>
                                Role: {item.roleLabel ?? item.roleCode}
                              </div>
                              {item.remark ? (
                                <div className='text-muted-foreground mt-1 text-sm'>
                                  {item.remark}
                                </div>
                              ) : null}
                            </div>
                            {canManageCustomers ? (
                              <div className='flex gap-2'>
                                <Button
                                  variant='outline'
                                  size='sm'
                                  onClick={() => {
                                    setEditingCustomer(item);
                                    setCustomerOpen(true);
                                  }}
                                >
                                  <Icons.edit className='mr-2 h-4 w-4' /> Edit
                                </Button>
                                <Button
                                  variant='outline'
                                  size='sm'
                                  onClick={() => setDeleteCustomerId(item.id)}
                                >
                                  <Icons.trash className='mr-2 h-4 w-4' /> Delete
                                </Button>
                              </div>
                            ) : null}
                          </div>
                        ))
                      )}
                    </CardContent>
                  </Card>
                </TabsContent>

                <TabsContent value='topics'>
                  <Card>
                    <CardHeader className='flex flex-row items-center justify-between'>
                      <div>
                        <CardTitle>Topics</CardTitle>
                        <CardDescription>
                          Scope, exclusions, payment terms, and other document sections.
                        </CardDescription>
                      </div>
                      {canManageTopics ? (
                        <Button
                          onClick={() => {
                            setEditingTopic(undefined);
                            setTopicOpen(true);
                          }}
                        >
                          <Icons.add className='mr-2 h-4 w-4' /> Add Topic
                        </Button>
                      ) : null}
                    </CardHeader>
                    <CardContent className='space-y-4'>
                      {!topicsData.items.length ? (
                        <EmptyState message='No quotation topics yet.' />
                      ) : (
                        topicsData.items.map((topic) => (
                          <div key={topic.id} className='rounded-lg border p-4'>
                            <div className='mb-3 flex items-center justify-between gap-4'>
                              <div>
                                <div className='font-medium'>{topic.title}</div>
                                <div className='text-muted-foreground text-sm'>
                                  {topicTypeMap.get(topic.topicType)?.label ?? topic.topicType}
                                </div>
                              </div>
                              {canManageTopics ? (
                                <div className='flex gap-2'>
                                  <Button
                                    variant='outline'
                                    size='sm'
                                    onClick={() => {
                                      setEditingTopic(topic);
                                      setTopicOpen(true);
                                    }}
                                  >
                                    <Icons.edit className='mr-2 h-4 w-4' /> Edit
                                  </Button>
                                  <Button
                                    variant='outline'
                                    size='sm'
                                    onClick={() => setDeleteTopicId(topic.id)}
                                  >
                                    <Icons.trash className='mr-2 h-4 w-4' /> Delete
                                  </Button>
                                </div>
                              ) : null}
                            </div>
                            <ul className='list-disc space-y-2 pl-5 text-sm'>
                              {topic.items.map((item) => (
                                <li key={item.id}>{item.content}</li>
                              ))}
                            </ul>
                          </div>
                        ))
                      )}
                    </CardContent>
                  </Card>
                </TabsContent>

                <TabsContent value='followups'>
                  <Card>
                    <CardHeader className='flex flex-row items-center justify-between'>
                      <div>
                        <CardTitle>Follow-ups</CardTitle>
                        <CardDescription>Commercial chasing and response history.</CardDescription>
                      </div>
                      {canManageFollowups ? (
                        <Button
                          onClick={() => {
                            setEditingFollowup(undefined);
                            setFollowupOpen(true);
                          }}
                        >
                          <Icons.add className='mr-2 h-4 w-4' /> Add Follow-up
                        </Button>
                      ) : null}
                    </CardHeader>
                    <CardContent className='space-y-3'>
                      {!followupsData.items.length ? (
                        <EmptyState message='No quotation follow-ups yet.' />
                      ) : (
                        followupsData.items.map((item) => (
                          <div key={item.id} className='rounded-lg border p-4'>
                            <div className='flex items-start justify-between gap-4'>
                              <div className='space-y-1'>
                                <div className='font-medium'>
                                  {followupTypeMap.get(item.followupType)?.label ??
                                    item.followupType}
                                </div>
                                <div className='text-muted-foreground text-sm'>
                                  {formatDate(item.followupDate)}
                                  {item.outcome ? ` - ${item.outcome}` : ''}
                                </div>
                                <div className='text-sm'>{item.notes || '-'}</div>
                              </div>
                              {canManageFollowups ? (
                                <div className='flex gap-2'>
                                  <Button
                                    variant='outline'
                                    size='sm'
                                    onClick={() => {
                                      setEditingFollowup(item);
                                      setFollowupOpen(true);
                                    }}
                                  >
                                    <Icons.edit className='mr-2 h-4 w-4' /> Edit
                                  </Button>
                                  <Button
                                    variant='outline'
                                    size='sm'
                                    onClick={() => setDeleteFollowupId(item.id)}
                                  >
                                    <Icons.trash className='mr-2 h-4 w-4' /> Delete
                                  </Button>
                                </div>
                              ) : null}
                            </div>
                          </div>
                        ))
                      )}
                    </CardContent>
                  </Card>
                </TabsContent>

                <TabsContent value='attachments'>
                  <Card>
                    <CardHeader className='flex flex-row items-center justify-between'>
                      <div>
                        <CardTitle>Attachments</CardTitle>
                        <CardDescription>
                          Metadata only in Task E, ready for storage integration later.
                        </CardDescription>
                      </div>
                      {canManageAttachments ? (
                        <Button
                          onClick={() => {
                            setEditingAttachment(undefined);
                            setAttachmentOpen(true);
                          }}
                        >
                          <Icons.add className='mr-2 h-4 w-4' /> Add Attachment
                        </Button>
                      ) : null}
                    </CardHeader>
                    <CardContent className='space-y-3'>
                      {!attachmentsData.items.length ? (
                        <EmptyState message='No attachment metadata yet.' />
                      ) : (
                        attachmentsData.items.map((item) => (
                          <div
                            key={item.id}
                            className='flex items-center justify-between rounded-lg border p-4'
                          >
                            <div>
                              <div className='font-medium'>{item.originalFileName}</div>
                              <div className='text-muted-foreground text-sm'>
                                {item.fileType || 'Unknown type'}
                                {item.fileSize ? ` - ${formatNumber(item.fileSize)} bytes` : ''}
                              </div>
                            </div>
                            {canManageAttachments ? (
                              <div className='flex gap-2'>
                                <Button
                                  variant='outline'
                                  size='sm'
                                  onClick={() => {
                                    setEditingAttachment(item);
                                    setAttachmentOpen(true);
                                  }}
                                >
                                  <Icons.edit className='mr-2 h-4 w-4' /> Edit
                                </Button>
                                <Button
                                  variant='outline'
                                  size='sm'
                                  onClick={() => setDeleteAttachmentId(item.id)}
                                >
                                  <Icons.trash className='mr-2 h-4 w-4' /> Delete
                                </Button>
                              </div>
                            ) : null}
                          </div>
                        ))
                      )}
                    </CardContent>
                  </Card>
                </TabsContent>

                <TabsContent value='activity'>
                  <AuditLogTab
                    items={data.activity}
                    emptyMessage='No audit log recorded yet.'
                    description='System-generated immutable history for this quotation and its child records.'
                  />
                </TabsContent>

                <TabsContent value='approval'>
                  <QuotationApprovalTab
                    quotationId={quotationId}
                    quotationStatusCode={status?.code ?? null}
                    canSubmitApproval={canSubmitApproval}
                    canApproveApproval={canApproveApproval}
                    canRejectApproval={canRejectApproval}
                    canReturnApproval={canReturnApproval}
                    activeBusinessRole={activeBusinessRole}
                    isOrgAdmin={isOrgAdmin}
                    currentUserId={currentUserId}
                  />
                </TabsContent>

                <TabsContent value='documents'>
                  <div className='flex flex-col gap-6'>
                    <Card>
                      <CardHeader>
                        <CardTitle>Documents</CardTitle>
                        <CardDescription>
                          Working quotation previews generated from live data.
                        </CardDescription>
                      </CardHeader>
                      <CardContent className='grid gap-4 xl:grid-cols-2'>
                        <Card>
                          <CardHeader>
                            <CardTitle>Quotation PDF Preview</CardTitle>
                            <CardDescription>
                              Working preview generated from current quotation data. Approval and
                              customer package generation are not required.
                            </CardDescription>
                          </CardHeader>
                          <CardContent className='flex flex-col gap-4'>
                            <div className='grid gap-4 md:grid-cols-3'>
                              <FieldItem label='Template' value='Active PDFMe template' />
                              <FieldItem label='Item Version' value='product-v1' />
                              <FieldItem label='Approval Required' value='No' />
                            </div>
                            <div className='flex flex-wrap gap-2'>
                              {canPreviewPdf ? (
                                <Button asChild variant='outline'>
                                  <Link
                                    href={`/api/crm/quotations/${quotationId}/pdf-preview`}
                                    target='_blank'
                                  >
                                    <Icons.eyeOff className='mr-2 h-4 w-4' /> Preview
                                  </Link>
                                </Button>
                              ) : (
                                <Button variant='outline' disabled>
                                  <Icons.eyeOff className='mr-2 h-4 w-4' /> Preview
                                </Button>
                              )}
                              {canPreviewPdf ? (
                                <Button asChild variant='outline'>
                                  <Link
                                    href={`/api/crm/quotations/${quotationId}/pdf-preview?templateVariant=product-v1`}
                                    target='_blank'
                                  >
                                    <Icons.badgeCheck className='mr-2 h-4 w-4' /> Preview Item
                                    Version
                                  </Link>
                                </Button>
                              ) : (
                                <Button variant='outline' disabled>
                                  <Icons.badgeCheck className='mr-2 h-4 w-4' /> Preview Item Version
                                </Button>
                              )}
                              {canPreviewDocument ? (
                                <Button asChild variant='outline'>
                                  <Link href='#working-document-preview'>
                                    <Icons.eyeOff className='mr-2 h-4 w-4' /> Preview Data
                                  </Link>
                                </Button>
                              ) : null}
                            </div>
                          </CardContent>
                        </Card>
                      </CardContent>
                    </Card>

                    {canPreviewDocument ? (
                      <div id='working-document-preview' className='scroll-mt-24'>
                        <QuotationDocumentPreview quotationId={quotationId} />
                      </div>
                    ) : (
                      <Card>
                        <CardHeader>
                          <CardTitle>Working Document Preview</CardTitle>
                          <CardDescription>
                            Preview permission is required to load working document data.
                          </CardDescription>
                        </CardHeader>
                        <CardContent>
                          <EmptyState message='You do not have access to quotation document preview.' />
                        </CardContent>
                      </Card>
                    )}
                  </div>
                </TabsContent>

                <TabsContent value='customer-package'>
                  <Card>
                    <CardHeader className='flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between'>
                      <div>
                        <CardTitle>Customer Package</CardTitle>
                        <CardDescription>
                          Operational detail for the assembled customer-deliverable package.
                        </CardDescription>
                      </div>
                      <div className='flex flex-wrap gap-2'>
                        {canGenerateApprovedPdf && !hasOfficialDocument ? (
                          <Button
                            variant='outline'
                            isLoading={createApprovedPdf.isPending}
                            onClick={() => createApprovedPdf.mutate()}
                          >
                            <Icons.badgeCheck className='mr-2 h-4 w-4' />
                            Generate Official PDF
                          </Button>
                        ) : null}
                        {canGenerateCustomerPackage ? (
                          <Button
                            variant='outline'
                            disabled={!hasOfficialDocument}
                            isLoading={generateCustomerPackage.isPending}
                            onClick={() =>
                              customerPackage
                                ? setConfirmRegenerateOpen(true)
                                : generateCustomerPackage.mutate({
                                    quotationId
                                  })
                            }
                          >
                            <Icons.badgeCheck className='mr-2 h-4 w-4' />
                            {customerPackageActionLabel}
                          </Button>
                        ) : null}
                        {canPreviewCustomerPackage && customerPackage ? (
                          <Button asChild variant='outline'>
                            <Link
                              href={`/api/crm/quotations/${quotationId}/assembled-pdf`}
                              target='_blank'
                            >
                              <Icons.eyeOff className='mr-2 h-4 w-4' /> Preview Package
                            </Link>
                          </Button>
                        ) : (
                          <Button variant='outline' disabled>
                            <Icons.eyeOff className='mr-2 h-4 w-4' /> Preview Package
                          </Button>
                        )}
                        {canDownloadCustomerPackage ? (
                          <Button
                            variant='outline'
                            disabled={!customerPackage}
                            isLoading={downloadCustomerPackage.isPending}
                            onClick={() => downloadCustomerPackage.mutate()}
                          >
                            <Icons.download className='mr-2 h-4 w-4' /> Download Package
                          </Button>
                        ) : null}
                      </div>
                    </CardHeader>
                    <CardContent className='flex flex-col gap-4'>
                      {!canGenerateCustomerPackage &&
                      !canDownloadCustomerPackage &&
                      !canPreviewCustomerPackage ? (
                        <EmptyState message='You do not have permission to generate or download customer package.' />
                      ) : (
                        <>
                          <div className='grid gap-4 md:grid-cols-2 xl:grid-cols-4'>
                            <FieldItem label='Status' value={customerPackageStatusLabel} />
                            <FieldItem
                              label='Generated At'
                              value={
                                customerPackage?.generatedAt
                                  ? formatDateTime(customerPackage.generatedAt)
                                  : null
                              }
                            />
                            <FieldItem
                              label='Generated By'
                              value={
                                customerPackage?.generatedByName ??
                                customerPackage?.generatedBy ??
                                null
                              }
                            />
                            <FieldItem
                              label='Page Count'
                              value={
                                customerPackage?.pageCount !== null &&
                                customerPackage?.pageCount !== undefined
                                  ? String(customerPackage.pageCount)
                                  : null
                              }
                            />
                            <FieldItem
                              label='File Size'
                              value={
                                customerPackage?.fileSize
                                  ? `${formatNumber(customerPackage.fileSize)} bytes`
                                  : null
                              }
                            />
                            <FieldItem
                              label='Checksum'
                              value={
                                customerPackage?.checksum
                                  ? customerPackage.checksum.slice(0, 16)
                                  : null
                              }
                            />
                            <FieldItem
                              label='File Name'
                              value={customerPackage?.fileName ?? null}
                            />
                            <FieldItem
                              label='Included Documents'
                              value={
                                customerPackage?.includedDocuments.length
                                  ? String(customerPackage.includedDocuments.length)
                                  : null
                              }
                            />
                          </div>
                          <div className='rounded-lg border border-dashed p-4 text-sm'>
                            {customerPackageStatusDescription}
                          </div>
                          {customerPackage?.warnings.length ? (
                            <div className='flex flex-col gap-2'>
                              <div className='text-sm font-medium'>Warnings</div>
                              {customerPackage.warnings.map((warning) => (
                                <div
                                  key={`${warning.code}-${warning.role}`}
                                  className='rounded-lg border p-3 text-sm'
                                >
                                  {warning.message}
                                </div>
                              ))}
                            </div>
                          ) : null}
                          <div className='flex flex-col gap-3'>
                            <div className='text-sm font-medium'>Included Documents</div>
                            {!customerPackage?.includedDocuments.length ? (
                              <EmptyState message='No assembled package has been generated yet.' />
                            ) : (
                              <div className='grid gap-3 md:grid-cols-2'>
                                {customerPackage.includedDocuments.map((item) => (
                                  <CustomerPackageSourceItem
                                    key={`${item.role}-${item.fileName}-${item.checksum ?? 'no-checksum'}`}
                                    item={item}
                                  />
                                ))}
                              </div>
                            )}
                          </div>
                        </>
                      )}
                    </CardContent>
                  </Card>
                </TabsContent>
              </Tabs>
            </CardContent>
          </Card>
        </div>

        <div className='space-y-6'>
          <Card>
            <CardHeader>
              <CardTitle>Revision Chain</CardTitle>
              <CardDescription>
                Family of quotations copied from the same parent record.
              </CardDescription>
            </CardHeader>
            <CardContent className='space-y-3'>
              {!revisionsData.items.length ? (
                <EmptyState message='No revisions yet.' />
              ) : (
                revisionsData.items.map((item) => (
                  <Link
                    key={item.id}
                    href={`/dashboard/crm/quotations/${item.id}`}
                    className='block rounded-lg border p-3 transition-colors hover:bg-muted/40'
                  >
                    <div className='flex items-center justify-between gap-3'>
                      <div>
                        <div className='font-medium'>{item.code}</div>
                        <div className='text-muted-foreground text-xs'>
                          {formatNumber(item.totalAmount)}
                        </div>
                      </div>
                      <Icons.arrowRight className='text-muted-foreground h-4 w-4' />
                    </div>
                  </Link>
                ))
              )}
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Record Snapshot</CardTitle>
              <CardDescription>Operational metadata for this quotation row.</CardDescription>
            </CardHeader>
            <CardContent className='space-y-4'>
              <FieldItem
                label='Created By'
                value={quotation.createdByName ?? quotation.createdBy}
              />
              <FieldItem
                label='Updated By'
                value={quotation.updatedByName ?? quotation.updatedBy}
              />
              <FieldItem label='Created At' value={formatDateTime(quotation.createdAt)} />
              <FieldItem label='Updated At' value={formatDateTime(quotation.updatedAt)} />
              <FieldItem
                label='Revision'
                value={`R${String(quotation.revision).padStart(2, '0')}`}
              />
              <FieldItem
                label='Approved At'
                value={quotation.approvedAt ? formatDateTime(quotation.approvedAt) : null}
              />
              <FieldItem
                label='Approved Template Version'
                value={quotation.approvedTemplateVersionId}
              />
              <FieldItem
                label='Approved Artifact'
                value={quotation.approvedArtifact?.fileName ?? null}
              />
              <FieldItem
                label='Artifact Generated By'
                value={
                  quotation.approvedArtifact?.generatedByName ??
                  quotation.approvedArtifact?.generatedBy ??
                  null
                }
              />
              <FieldItem
                label='Artifact Generated At'
                value={
                  quotation.approvedArtifact?.generatedAt
                    ? formatDateTime(quotation.approvedArtifact.generatedAt)
                    : null
                }
              />
              <FieldItem
                label='Artifact Checksum'
                value={quotation.approvedArtifact?.checksum?.slice(0, 16) ?? null}
              />
              <div className='space-y-2'>
                <div className='text-muted-foreground text-xs'>Artifact Status</div>
                <div className='flex flex-wrap items-center gap-2'>
                  {quotation.approvedArtifact ? (
                    <Badge
                      variant={
                        quotation.approvedArtifact.status === 'locked' ? 'default' : 'secondary'
                      }
                    >
                      {quotation.approvedArtifact.status}
                    </Badge>
                  ) : (
                    <span className='text-sm'>-</span>
                  )}
                  {quotation.approvedArtifact?.lockedAt ? (
                    <span className='text-muted-foreground text-xs'>
                      Locked {formatDateTime(quotation.approvedArtifact.lockedAt)}
                    </span>
                  ) : null}
                </div>
              </div>
              {quotation.hasLegacyApprovedPdf ? (
                <div className='rounded-lg border border-dashed p-3 text-sm'>
                  <div className='font-medium'>Legacy approved PDF detected</div>
                  <div className='text-muted-foreground mt-1'>
                    This quotation still points to the old `public/generated` storage path and has
                    not been migrated into the artifact storage model yet.
                  </div>
                </div>
              ) : null}
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  );
}
