'use client';

import * as React from 'react';
import { useMutation, useSuspenseQuery } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Icons } from '@/components/icons';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Switch } from '@/components/ui/switch';
import {
  createApprovalWorkflowMutation,
  deleteApprovalWorkflowMutation,
  replaceApprovalWorkflowStepsMutation,
  updateApprovalWorkflowMutation
} from '../mutations';
import {
  approvalWorkflowByIdOptions,
  approvalWorkflowsQueryOptions
} from '../queries';
import type {
  ApprovalStepMutationPayload,
  ApprovalWorkflowDetail,
  ApprovalWorkflowMutationPayload
} from '../types';

type WorkflowState = {
  code: string;
  name: string;
  entityType: string;
  isActive: boolean;
};

type StepState = {
  stepNumber: string;
  roleCode: string;
  roleName: string;
  isRequired: boolean;
};

function toWorkflowState(workflow?: ApprovalWorkflowDetail): WorkflowState {
  return {
    code: workflow?.code ?? '',
    name: workflow?.name ?? '',
    entityType: workflow?.entityType ?? 'quotation',
    isActive: workflow?.isActive ?? true
  };
}

function toStepState(workflow?: ApprovalWorkflowDetail): StepState[] {
  return (
    workflow?.steps.map((step) => ({
      stepNumber: String(step.stepNumber),
      roleCode: step.roleCode,
      roleName: step.roleName,
      isRequired: step.isRequired
    })) ?? [{ stepNumber: '1', roleCode: 'sales_manager', roleName: 'Sales Manager', isRequired: true }]
  );
}

function WorkflowDialog({
  open,
  onOpenChange,
  workflow
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  workflow?: ApprovalWorkflowDetail;
}) {
  const [state, setState] = React.useState<WorkflowState>(toWorkflowState(workflow));
  const createMutation = useMutation({
    ...createApprovalWorkflowMutation,
    onSuccess: () => {
      toast.success('Workflow created');
      onOpenChange(false);
    },
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Create failed')
  });
  const updateMutation = useMutation({
    ...updateApprovalWorkflowMutation,
    onSuccess: () => {
      toast.success('Workflow updated');
      onOpenChange(false);
    },
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Update failed')
  });

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

  async function onSubmit(event: React.FormEvent) {
    event.preventDefault();
    const payload: ApprovalWorkflowMutationPayload = {
      code: state.code,
      name: state.name,
      entityType: state.entityType,
      isActive: state.isActive
    };

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

    await createMutation.mutateAsync(payload);
  }

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

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{workflow ? 'Edit Workflow' : 'Create Workflow'}</DialogTitle>
          <DialogDescription>Sequential workflow only. No parallel or conditional logic is introduced here.</DialogDescription>
        </DialogHeader>
        <form onSubmit={onSubmit} className='grid gap-4'>
          <Input placeholder='Workflow code' value={state.code} onChange={(e) => setState((current) => ({ ...current, code: e.target.value }))} />
          <Input placeholder='Workflow name' value={state.name} onChange={(e) => setState((current) => ({ ...current, name: e.target.value }))} />
          <Input placeholder='Entity type' value={state.entityType} onChange={(e) => setState((current) => ({ ...current, entityType: e.target.value }))} />
          <div className='flex items-center justify-between rounded-lg border px-4 py-3'>
            <div>
              <div className='font-medium'>Active</div>
              <div className='text-muted-foreground text-sm'>Inactive workflows stay available in audit history only.</div>
            </div>
            <Switch checked={state.isActive} onCheckedChange={(checked) => setState((current) => ({ ...current, isActive: checked }))} />
          </div>
          <DialogFooter>
            <Button type='button' variant='outline' onClick={() => onOpenChange(false)}>
              Cancel
            </Button>
            <Button type='submit' isLoading={isPending}>
              {workflow ? 'Save Workflow' : 'Create Workflow'}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function StepsDialog({
  workflow,
  open,
  onOpenChange
}: {
  workflow: ApprovalWorkflowDetail;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const [steps, setSteps] = React.useState<StepState[]>(toStepState(workflow));
  const replaceMutation = useMutation({
    ...replaceApprovalWorkflowStepsMutation,
    onSuccess: () => {
      toast.success('Workflow steps updated');
      onOpenChange(false);
    },
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Update failed')
  });

  React.useEffect(() => {
    if (open) {
      setSteps(toStepState(workflow));
    }
  }, [open, workflow]);

  function updateStep(index: number, field: keyof StepState, value: string | boolean) {
    setSteps((current) =>
      current.map((step, stepIndex) =>
        stepIndex === index ? { ...step, [field]: value } : step
      )
    );
  }

  async function onSubmit(event: React.FormEvent) {
    event.preventDefault();
    const payload: ApprovalStepMutationPayload[] = steps.map((step, index) => ({
      stepNumber: Number(step.stepNumber || index + 1),
      roleCode: step.roleCode,
      roleName: step.roleName,
      isRequired: step.isRequired
    }));

    await replaceMutation.mutateAsync({ workflowId: workflow.id, steps: payload });
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className='sm:max-w-4xl'>
        <DialogHeader>
          <DialogTitle>Manage Steps</DialogTitle>
          <DialogDescription>Each step resolves to a CRM business role and runs strictly in order.</DialogDescription>
        </DialogHeader>
        <form onSubmit={onSubmit} className='space-y-4'>
          {steps.map((step, index) => (
            <div key={`${index}-${step.roleCode}`} className='grid gap-3 rounded-lg border p-4 md:grid-cols-4'>
              <Input placeholder='Step no.' value={step.stepNumber} onChange={(e) => updateStep(index, 'stepNumber', e.target.value)} />
              <Input placeholder='Role code' value={step.roleCode} onChange={(e) => updateStep(index, 'roleCode', e.target.value)} />
              <Input placeholder='Role name' value={step.roleName} onChange={(e) => updateStep(index, 'roleName', e.target.value)} />
              <div className='flex items-center justify-between rounded-lg border px-3 py-2'>
                <span className='text-sm font-medium'>Required</span>
                <Switch checked={step.isRequired} onCheckedChange={(checked) => updateStep(index, 'isRequired', checked)} />
              </div>
            </div>
          ))}
          <Button
            type='button'
            variant='outline'
            onClick={() =>
              setSteps((current) => [
                ...current,
                {
                  stepNumber: String(current.length + 1),
                  roleCode: '',
                  roleName: '',
                  isRequired: true
                }
              ])
            }
          >
            <Icons.add className='mr-2 h-4 w-4' />
            Add Step
          </Button>
          <DialogFooter>
            <Button type='button' variant='outline' onClick={() => onOpenChange(false)}>
              Cancel
            </Button>
            <Button type='submit' isLoading={replaceMutation.isPending}>
              Save Steps
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function WorkflowDetailActions({ workflowId }: { workflowId: string }) {
  const { data } = useSuspenseQuery(approvalWorkflowByIdOptions(workflowId));
  const workflow = data.workflow;
  const [workflowDialogOpen, setWorkflowDialogOpen] = React.useState(false);
  const [stepsDialogOpen, setStepsDialogOpen] = React.useState(false);
  const deleteMutation = useMutation({
    ...deleteApprovalWorkflowMutation,
    onSuccess: () => toast.success('Workflow deleted'),
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Delete failed')
  });

  return (
    <>
      <div className='flex gap-2'>
        <Button variant='outline' onClick={() => setWorkflowDialogOpen(true)}>
          Edit Workflow
        </Button>
        <Button variant='outline' onClick={() => setStepsDialogOpen(true)}>
          Manage Steps
        </Button>
        <Button variant='outline' onClick={() => deleteMutation.mutate(workflow.id)} isLoading={deleteMutation.isPending}>
          Delete
        </Button>
      </div>
      <div className='mt-3 grid gap-3 md:grid-cols-2 xl:grid-cols-4'>
        {workflow.steps.map((step) => (
          <div key={step.id} className='rounded-lg border p-4'>
            <div className='font-medium'>Step {step.stepNumber}</div>
            <div className='text-muted-foreground mt-1 text-sm'>{step.roleName}</div>
            <div className='mt-2 flex gap-2'>
              <Badge variant='outline'>{step.roleCode}</Badge>
              <Badge variant={step.isRequired ? 'secondary' : 'outline'}>
                {step.isRequired ? 'Required' : 'Optional'}
              </Badge>
            </div>
          </div>
        ))}
      </div>
      <WorkflowDialog open={workflowDialogOpen} onOpenChange={setWorkflowDialogOpen} workflow={workflow} />
      <StepsDialog open={stepsDialogOpen} onOpenChange={setStepsDialogOpen} workflow={workflow} />
    </>
  );
}

export function ApprovalWorkflowSettings() {
  const { data } = useSuspenseQuery(approvalWorkflowsQueryOptions());
  const [createOpen, setCreateOpen] = React.useState(false);

  return (
    <div className='space-y-6'>
      <div className='flex items-center justify-between gap-4 rounded-lg border p-4'>
        <div>
          <div className='font-medium'>Approval Workflow Admin</div>
          <div className='text-muted-foreground text-sm'>Configure sequential CRM approval workflows and business-role steps.</div>
        </div>
        <Button onClick={() => setCreateOpen(true)}>
          <Icons.add className='mr-2 h-4 w-4' />
          Create Workflow
        </Button>
      </div>

      {data.items.length === 0 ? (
        <div className='text-muted-foreground rounded-lg border border-dashed p-8 text-center text-sm'>
          No approval workflows configured.
        </div>
      ) : (
        data.items.map((workflow) => (
          <div key={workflow.id} className='rounded-xl border p-5'>
            <div className='flex flex-wrap items-start justify-between gap-4'>
              <div>
                <div className='text-xl font-semibold'>{workflow.name}</div>
                <div className='text-muted-foreground text-sm'>
                  {workflow.code} • {workflow.entityType}
                </div>
              </div>
              <div className='flex gap-2'>
                <Badge variant={workflow.isActive ? 'secondary' : 'outline'}>
                  {workflow.isActive ? 'Active' : 'Inactive'}
                </Badge>
                <Badge variant='outline'>{workflow.stepCount} steps</Badge>
              </div>
            </div>
            <React.Suspense fallback={<div className='text-muted-foreground mt-4 text-sm'>Loading workflow detail...</div>}>
              <WorkflowDetailActions workflowId={workflow.id} />
            </React.Suspense>
          </div>
        ))
      )}

      <WorkflowDialog open={createOpen} onOpenChange={setCreateOpen} />
    </div>
  );
}
