'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,
  DialogFooter,
  DialogHeader,
  DialogTitle
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea';
import { approvalWorkflowsQueryOptions } from '@/features/foundation/approval/queries';
import {
  createApprovalReminderPolicyMutation,
  deleteApprovalReminderPolicyMutation,
  runApprovalAutomationMutation,
  updateApprovalReminderPolicyMutation
} from '../api/mutations';
import {
  approvalReminderPoliciesOptions,
  pendingApprovalAutomationQueueOptions
} from '../api/queries';
import type { ReminderPolicyItem, ReminderPolicyPayload } from '../api/types';

type ReminderFormState = {
  workflowId: string;
  stepNumber: string;
  slaHours: string;
  reminderOffsets: string;
  timeoutAction: ReminderPolicyPayload['timeoutAction'];
  isActive: boolean;
};

function toReminderState(policy?: ReminderPolicyItem): ReminderFormState {
  return {
    workflowId: policy?.workflowId ?? '',
    stepNumber: String(policy?.stepNumber ?? 1),
    slaHours: String(policy?.slaHours ?? 24),
    reminderOffsets: policy?.reminderOffsetsHours.join(', ') ?? '24, 48',
    timeoutAction: policy?.timeoutAction ?? 'none',
    isActive: policy?.isActive ?? true
  };
}

function parseOffsets(value: string) {
  return value
    .split(',')
    .map((item) => Number(item.trim()))
    .filter((item) => Number.isFinite(item) && item > 0);
}

function ReminderPolicyDialog({
  open,
  onOpenChange,
  policy
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  policy?: ReminderPolicyItem;
}) {
  const workflowsQuery = useSuspenseQuery(approvalWorkflowsQueryOptions());
  const [state, setState] = React.useState<ReminderFormState>(toReminderState(policy));
  const createMutation = useMutation({
    ...createApprovalReminderPolicyMutation,
    onSuccess: () => {
      toast.success('Reminder policy created');
      onOpenChange(false);
    },
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Create failed')
  });
  const updateMutation = useMutation({
    ...updateApprovalReminderPolicyMutation,
    onSuccess: () => {
      toast.success('Reminder policy updated');
      onOpenChange(false);
    },
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Update failed')
  });

  React.useEffect(() => {
    if (open) {
      const workflowId = policy?.workflowId ?? workflowsQuery.data.items[0]?.id ?? '';
      setState({ ...toReminderState(policy), workflowId });
    }
  }, [open, policy, workflowsQuery.data.items]);

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

  async function onSubmit(event: React.FormEvent) {
    event.preventDefault();
    const payload: ReminderPolicyPayload = {
      workflowId: state.workflowId,
      stepNumber: Number(state.stepNumber),
      slaHours: Number(state.slaHours),
      reminderOffsetsHours: parseOffsets(state.reminderOffsets),
      timeoutAction: state.timeoutAction,
      isActive: state.isActive,
      calendarMode: 'calendar_days'
    };

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

    await createMutation.mutateAsync(payload);
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className='sm:max-w-2xl'>
        <DialogHeader>
          <DialogTitle>{policy ? 'Edit Reminder Policy' : 'Create Reminder Policy'}</DialogTitle>
        </DialogHeader>
        <form className='space-y-4' onSubmit={onSubmit}>
          <div className='grid gap-4 md:grid-cols-2'>
            <div className='space-y-2'>
              <div className='text-sm font-medium'>Workflow</div>
              <select
                className='border-input bg-background flex h-10 w-full rounded-md border px-3 py-2 text-sm'
                value={state.workflowId}
                onChange={(event) =>
                  setState((current) => ({ ...current, workflowId: event.target.value }))
                }
              >
                {workflowsQuery.data.items.map((workflow) => (
                  <option key={workflow.id} value={workflow.id}>
                    {workflow.name}
                  </option>
                ))}
              </select>
            </div>
            <div className='space-y-2'>
              <div className='text-sm font-medium'>Step Number</div>
              <Input
                type='number'
                min={1}
                value={state.stepNumber}
                onChange={(event) =>
                  setState((current) => ({ ...current, stepNumber: event.target.value }))
                }
              />
            </div>
          </div>
          <div className='grid gap-4 md:grid-cols-2'>
            <div className='space-y-2'>
              <div className='text-sm font-medium'>SLA Hours</div>
              <Input
                type='number'
                min={1}
                value={state.slaHours}
                onChange={(event) =>
                  setState((current) => ({ ...current, slaHours: event.target.value }))
                }
              />
            </div>
            <div className='space-y-2'>
              <div className='text-sm font-medium'>Timeout Action</div>
              <select
                className='border-input bg-background flex h-10 w-full rounded-md border px-3 py-2 text-sm'
                value={state.timeoutAction}
                onChange={(event) =>
                  setState((current) => ({
                    ...current,
                    timeoutAction: event.target.value as ReminderFormState['timeoutAction']
                  }))
                }
              >
                <option value='none'>None</option>
                <option value='auto_reject'>Auto Reject</option>
                <option value='auto_cancel'>Auto Cancel</option>
                <option value='auto_escalate'>Auto Escalate</option>
              </select>
            </div>
          </div>
          <div className='space-y-2'>
            <div className='text-sm font-medium'>Reminder Offsets (hours)</div>
            <Textarea
              value={state.reminderOffsets}
              onChange={(event) =>
                setState((current) => ({ ...current, reminderOffsets: event.target.value }))
              }
              placeholder='24, 48, 72'
            />
            <div className='text-muted-foreground text-xs'>
              Comma-separated hours after step start.
            </div>
          </div>
          <div className='flex items-center justify-between rounded-lg border px-4 py-3'>
            <div>
              <div className='font-medium'>Active Policy</div>
              <div className='text-muted-foreground text-sm'>
                Inactive policies are ignored by the scheduler.
              </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}>
              {policy ? 'Save Policy' : 'Create Policy'}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

export function ReminderPolicySettings() {
  const reminderPoliciesQuery = useSuspenseQuery(approvalReminderPoliciesOptions());
  const pendingQueueQuery = useSuspenseQuery(pendingApprovalAutomationQueueOptions());
  const [createOpen, setCreateOpen] = React.useState(false);
  const [editingPolicy, setEditingPolicy] = React.useState<ReminderPolicyItem | null>(null);
  const runAutomation = useMutation({
    ...runApprovalAutomationMutation,
    onSuccess: (result) => {
      toast.success(`Automation completed. ${result.processedCount} request(s) checked.`);
    },
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Run failed')
  });
  const deleteMutation = useMutation({
    ...deleteApprovalReminderPolicyMutation,
    onSuccess: () => toast.success('Reminder policy deleted'),
    onError: (error) => toast.error(error instanceof Error ? error.message : 'Delete failed')
  });

  const queue = pendingQueueQuery.data;

  return (
    <div className='space-y-6'>
      <div className='grid gap-4 md:grid-cols-4'>
        <div className='rounded-lg border p-4'>
          <div className='text-muted-foreground text-xs'>Pending</div>
          <div className='text-2xl font-semibold'>{queue.summary.pending}</div>
        </div>
        <div className='rounded-lg border p-4'>
          <div className='text-muted-foreground text-xs'>Due Today</div>
          <div className='text-2xl font-semibold'>{queue.summary.dueToday}</div>
        </div>
        <div className='rounded-lg border p-4'>
          <div className='text-muted-foreground text-xs'>Overdue</div>
          <div className='text-2xl font-semibold'>{queue.summary.overdue}</div>
        </div>
        <div className='rounded-lg border p-4'>
          <div className='text-muted-foreground text-xs'>Escalated</div>
          <div className='text-2xl font-semibold'>{queue.summary.escalated}</div>
        </div>
      </div>

      <div className='flex items-center justify-between rounded-lg border p-4'>
        <div>
          <div className='font-medium'>Approval Automation Scheduler</div>
          <div className='text-muted-foreground text-sm'>
            Manually execute reminder, escalation, and timeout checks for all pending approvals.
          </div>
        </div>
        <div className='flex gap-2'>
          <Button variant='outline' onClick={() => setCreateOpen(true)}>
            <Icons.add className='mr-2 h-4 w-4' />
            Create Policy
          </Button>
          <Button onClick={() => runAutomation.mutate()} isLoading={runAutomation.isPending}>
            Run Automation
          </Button>
        </div>
      </div>

      <div className='rounded-lg border p-4'>
        <div className='mb-4 font-medium'>Pending Queue Monitor</div>
        {queue.items.length === 0 ? (
          <div className='text-muted-foreground text-sm'>No pending approvals right now.</div>
        ) : (
          <div className='space-y-3'>
            {queue.items.slice(0, 10).map((item) => (
              <div key={item.approvalRequestId} className='rounded-lg border p-3'>
                <div className='flex flex-wrap items-center justify-between gap-2'>
                  <div>
                    <div className='font-medium'>
                      {item.workflowName} | Step {item.currentStep}
                    </div>
                    <div className='text-muted-foreground text-sm'>
                      {item.currentStepRoleName ?? '-'} | Waiting {item.waitingHours}h
                    </div>
                  </div>
                  <div className='flex flex-wrap gap-2'>
                    {item.isOverdue ? <Badge variant='destructive'>Overdue</Badge> : null}
                    {item.isDueToday ? <Badge variant='secondary'>Due Today</Badge> : null}
                    {item.isEscalated ? <Badge variant='outline'>Escalated</Badge> : null}
                    {item.slaHours !== null ? (
                      <Badge variant='outline'>SLA {item.slaHours}h</Badge>
                    ) : null}
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      <div className='space-y-4'>
        {reminderPoliciesQuery.data.items.map((policy) => (
          <div key={policy.id} className='rounded-lg border p-4'>
            <div className='flex items-start justify-between gap-4'>
              <div>
                <div className='font-medium'>
                  {policy.workflowName} | Step {policy.stepNumber}
                </div>
                <div className='text-muted-foreground mt-1 text-sm'>
                  Reminders at {policy.reminderOffsetsHours.join(', ') || '-'} hours
                </div>
                <div className='mt-3 flex flex-wrap gap-2'>
                  <Badge variant='outline'>SLA {policy.slaHours}h</Badge>
                  <Badge variant='outline'>{policy.timeoutAction}</Badge>
                  <Badge variant={policy.isActive ? 'secondary' : 'outline'}>
                    {policy.isActive ? 'Active' : 'Inactive'}
                  </Badge>
                </div>
              </div>
              <div className='flex gap-2'>
                <Button size='sm' variant='outline' onClick={() => setEditingPolicy(policy)}>
                  Edit
                </Button>
                <Button
                  size='sm'
                  variant='outline'
                  onClick={() => deleteMutation.mutate(policy.id)}
                  isLoading={deleteMutation.isPending}
                >
                  Delete
                </Button>
              </div>
            </div>
          </div>
        ))}
        {reminderPoliciesQuery.data.items.length === 0 ? (
          <div className='text-muted-foreground rounded-lg border border-dashed p-8 text-center text-sm'>
            No reminder policies configured yet.
          </div>
        ) : null}
      </div>

      <ReminderPolicyDialog open={createOpen} onOpenChange={setCreateOpen} />
      <ReminderPolicyDialog
        open={editingPolicy !== null}
        onOpenChange={(open) => {
          if (!open) {
            setEditingPolicy(null);
          }
        }}
        policy={editingPolicy ?? undefined}
      />
    </div>
  );
}
