'use client';

import { useEffect, useMemo, useState } from 'react';
import { useMutation, useSuspenseQuery } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import {
  createCrmUserRoleAssignmentMutation,
  deleteCrmUserRoleAssignmentMutation,
  updateCrmUserRoleAssignmentMutation
} from '../api/mutations';
import { crmUserRoleAssignmentsQueryOptions } from '../api/queries';
import type {
  CrmUserRoleAssignmentMutationPayload,
  CrmUserRoleAssignmentRecord,
  UpdateCrmUserRoleAssignmentPayload
} from '../api/types';

type AssignmentEditorState = {
  branchScopeMode: CrmUserRoleAssignmentMutationPayload['branchScopeMode'];
  branchScopeIds: string[];
  productTypeScopeMode: CrmUserRoleAssignmentMutationPayload['productTypeScopeMode'];
  productTypeScopeIds: string[];
  isPrimary: boolean;
  isActive: boolean;
};

const emptyCreateState: CrmUserRoleAssignmentMutationPayload = {
  userId: '',
  roleProfileId: '',
  branchScopeMode: 'inherit',
  branchScopeIds: [],
  productTypeScopeMode: 'inherit',
  productTypeScopeIds: [],
  isPrimary: false,
  isActive: true
};

function ScopeSelector(props: {
  label: string;
  mode: CrmUserRoleAssignmentMutationPayload['branchScopeMode'];
  ids: string[];
  options: Array<{ id: string; label: string; code: string }>;
  onModeChange: (value: CrmUserRoleAssignmentMutationPayload['branchScopeMode']) => void;
  onIdsChange: (value: string[]) => void;
}) {
  return (
    <div className='space-y-3'>
      <div className='space-y-2'>
        <Label>{props.label}</Label>
        <Select value={props.mode} onValueChange={props.onModeChange}>
          <SelectTrigger>
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value='inherit'>Inherit role profile</SelectItem>
            <SelectItem value='all'>All</SelectItem>
            <SelectItem value='selected'>Selected</SelectItem>
            <SelectItem value='none'>None</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {props.mode === 'selected' ? (
        <div className='grid gap-2 rounded-md border p-3 md:grid-cols-2'>
          {props.options.map((option) => {
            const checked = props.ids.includes(option.id);

            return (
              <label key={option.id} className='flex items-start gap-3 rounded-md border p-3'>
                <Checkbox
                  checked={checked}
                  onCheckedChange={(value) => {
                    props.onIdsChange(
                      value === true
                        ? [...new Set([...props.ids, option.id])]
                        : props.ids.filter((item) => item !== option.id)
                    );
                  }}
                />
                <div>
                  <div className='font-medium'>{option.label}</div>
                  <div className='text-muted-foreground text-xs'>{option.code}</div>
                </div>
              </label>
            );
          })}
        </div>
      ) : null}
    </div>
  );
}

export function UserRoleAssignmentsPage() {
  const { data } = useSuspenseQuery(crmUserRoleAssignmentsQueryOptions());
  const [selectedId, setSelectedId] = useState<string | null>(data.assignments[0]?.id ?? null);
  const [createState, setCreateState] =
    useState<CrmUserRoleAssignmentMutationPayload>(emptyCreateState);
  const [editorState, setEditorState] = useState<AssignmentEditorState | null>(null);
  const selectedAssignment = useMemo(
    () => data.assignments.find((assignment) => assignment.id === selectedId) ?? null,
    [data.assignments, selectedId]
  );

  useEffect(() => {
    if (!selectedAssignment) {
      setEditorState(null);
      return;
    }

    setEditorState({
      branchScopeMode: selectedAssignment.branchScopeMode,
      branchScopeIds: selectedAssignment.branchScopeIds,
      productTypeScopeMode: selectedAssignment.productTypeScopeMode,
      productTypeScopeIds: selectedAssignment.productTypeScopeIds,
      isPrimary: selectedAssignment.isPrimary,
      isActive: selectedAssignment.isActive
    });
  }, [selectedAssignment]);

  const createMutation = useMutation({
    ...createCrmUserRoleAssignmentMutation,
    onSuccess: () => {
      toast.success('CRM role assignment created successfully');
      setCreateState(emptyCreateState);
    },
    onError: (error) =>
      toast.error(
        error instanceof Error ? error.message : 'Unable to create CRM role assignment'
      )
  });

  const updateMutation = useMutation({
    ...updateCrmUserRoleAssignmentMutation,
    onSuccess: () => toast.success('CRM role assignment updated successfully'),
    onError: (error) =>
      toast.error(
        error instanceof Error ? error.message : 'Unable to update CRM role assignment'
      )
  });

  const deleteMutation = useMutation({
    ...deleteCrmUserRoleAssignmentMutation,
    onSuccess: () => {
      toast.success('CRM role assignment deleted successfully');
      setSelectedId(null);
    },
    onError: (error) =>
      toast.error(
        error instanceof Error ? error.message : 'Unable to delete CRM role assignment'
      )
  });

  async function handleCreate() {
    if (!createState.userId || !createState.roleProfileId) {
      toast.error('User and role profile are required');
      return;
    }

    await createMutation.mutateAsync(createState);
  }

  async function handleUpdate() {
    if (!selectedAssignment || !editorState) {
      return;
    }

    await updateMutation.mutateAsync({
      id: selectedAssignment.id,
      payload: editorState satisfies UpdateCrmUserRoleAssignmentPayload
    });
  }

  return (
    <div className='space-y-6'>
      <Card>
        <CardHeader>
          <CardTitle>Assign CRM Role</CardTitle>
          <CardDescription>
            One user can hold multiple CRM roles in the same organization. Primary role is for
            display; effective access unions across active assignments.
          </CardDescription>
        </CardHeader>
        <CardContent className='space-y-6'>
          <div className='grid gap-4 md:grid-cols-2'>
            <div className='space-y-2'>
              <Label>User</Label>
              <Select
                value={createState.userId}
                onValueChange={(value) => setCreateState({ ...createState, userId: value })}
              >
                <SelectTrigger>
                  <SelectValue placeholder='Select user' />
                </SelectTrigger>
                <SelectContent>
                  {data.users.map((user) => (
                    <SelectItem key={user.id} value={user.id}>
                      {user.name} ({user.email})
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className='space-y-2'>
              <Label>Role Profile</Label>
              <Select
                value={createState.roleProfileId}
                onValueChange={(value) =>
                  setCreateState({ ...createState, roleProfileId: value })
                }
              >
                <SelectTrigger>
                  <SelectValue placeholder='Select role profile' />
                </SelectTrigger>
                <SelectContent>
                  {data.roleProfiles.map((role) => (
                    <SelectItem key={role.id} value={role.id}>
                      {role.name} ({role.code})
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className='grid gap-6 xl:grid-cols-2'>
            <ScopeSelector
              label='Branch Scope'
              mode={createState.branchScopeMode}
              ids={createState.branchScopeIds}
              options={data.branches}
              onModeChange={(value) =>
                setCreateState({
                  ...createState,
                  branchScopeMode: value,
                  branchScopeIds: value === 'selected' ? createState.branchScopeIds : []
                })
              }
              onIdsChange={(value) => setCreateState({ ...createState, branchScopeIds: value })}
            />
            <ScopeSelector
              label='Product Type Scope'
              mode={createState.productTypeScopeMode}
              ids={createState.productTypeScopeIds}
              options={data.productTypes}
              onModeChange={(value) =>
                setCreateState({
                  ...createState,
                  productTypeScopeMode: value,
                  productTypeScopeIds: value === 'selected' ? createState.productTypeScopeIds : []
                })
              }
              onIdsChange={(value) =>
                setCreateState({ ...createState, productTypeScopeIds: value })
              }
            />
          </div>

          <div className='flex flex-wrap items-center gap-6'>
            <label className='flex items-center gap-3'>
              <Checkbox
                checked={createState.isPrimary}
                onCheckedChange={(value) =>
                  setCreateState({ ...createState, isPrimary: value === true })
                }
              />
              <span className='text-sm font-medium'>Primary role</span>
            </label>
            <label className='flex items-center gap-3'>
              <Checkbox
                checked={createState.isActive}
                onCheckedChange={(value) =>
                  setCreateState({ ...createState, isActive: value === true })
                }
              />
              <span className='text-sm font-medium'>Active</span>
            </label>
          </div>

          <Button onClick={() => void handleCreate()} isLoading={createMutation.isPending}>
            Assign Role
          </Button>
        </CardContent>
      </Card>

      <div className='grid gap-6 xl:grid-cols-[360px_minmax(0,1fr)]'>
        <Card>
          <CardHeader>
            <CardTitle>Existing Assignments</CardTitle>
            <CardDescription>
              Active and historical CRM role assignments in this organization.
            </CardDescription>
          </CardHeader>
          <CardContent className='space-y-3'>
            {data.assignments.map((assignment) => (
              <button
                key={assignment.id}
                type='button'
                onClick={() => setSelectedId(assignment.id)}
                className={`w-full rounded-lg border p-3 text-left transition ${
                  assignment.id === selectedId
                    ? 'border-primary bg-primary/5'
                    : 'hover:bg-muted/40'
                }`}
              >
                <div className='flex items-center justify-between gap-2'>
                  <div className='font-medium'>{assignment.userName}</div>
                  <div className='flex gap-2'>
                    {assignment.isPrimary ? <Badge>Primary</Badge> : null}
                    {!assignment.isActive ? <Badge variant='outline'>Inactive</Badge> : null}
                  </div>
                </div>
                <div className='text-muted-foreground mt-1 text-xs'>{assignment.userEmail}</div>
                <div className='mt-2 text-sm'>
                  {assignment.roleProfileName} ({assignment.roleProfileCode})
                </div>
              </button>
            ))}
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Assignment Detail</CardTitle>
            <CardDescription>
              Update scope, activation, and primary-role display for the selected CRM assignment.
            </CardDescription>
          </CardHeader>
          <CardContent className='space-y-6'>
            {!selectedAssignment || !editorState ? (
              <div className='text-muted-foreground rounded-lg border border-dashed p-8 text-center'>
                Select an assignment to edit.
              </div>
            ) : (
              <>
                <div className='grid gap-4 md:grid-cols-2'>
                  <div className='rounded-lg border p-4'>
                    <div className='text-muted-foreground text-xs'>User</div>
                    <div className='font-medium'>{selectedAssignment.userName}</div>
                    <div className='text-muted-foreground text-sm'>{selectedAssignment.userEmail}</div>
                  </div>
                  <div className='rounded-lg border p-4'>
                    <div className='text-muted-foreground text-xs'>Role Profile</div>
                    <div className='font-medium'>{selectedAssignment.roleProfileName}</div>
                    <div className='text-muted-foreground text-sm'>
                      {selectedAssignment.roleProfileCode}
                    </div>
                  </div>
                </div>

                <div className='grid gap-6 xl:grid-cols-2'>
                  <ScopeSelector
                    label='Branch Scope'
                    mode={editorState.branchScopeMode}
                    ids={editorState.branchScopeIds}
                    options={data.branches}
                    onModeChange={(value) =>
                      setEditorState({
                        ...editorState,
                        branchScopeMode: value,
                        branchScopeIds: value === 'selected' ? editorState.branchScopeIds : []
                      })
                    }
                    onIdsChange={(value) =>
                      setEditorState({ ...editorState, branchScopeIds: value })
                    }
                  />
                  <ScopeSelector
                    label='Product Type Scope'
                    mode={editorState.productTypeScopeMode}
                    ids={editorState.productTypeScopeIds}
                    options={data.productTypes}
                    onModeChange={(value) =>
                      setEditorState({
                        ...editorState,
                        productTypeScopeMode: value,
                        productTypeScopeIds:
                          value === 'selected' ? editorState.productTypeScopeIds : []
                      })
                    }
                    onIdsChange={(value) =>
                      setEditorState({ ...editorState, productTypeScopeIds: value })
                    }
                  />
                </div>

                <div className='flex flex-wrap items-center gap-6'>
                  <label className='flex items-center gap-3'>
                    <Checkbox
                      checked={editorState.isPrimary}
                      onCheckedChange={(value) =>
                        setEditorState({ ...editorState, isPrimary: value === true })
                      }
                    />
                    <span className='text-sm font-medium'>Primary role</span>
                  </label>
                  <label className='flex items-center gap-3'>
                    <Checkbox
                      checked={editorState.isActive}
                      onCheckedChange={(value) =>
                        setEditorState({ ...editorState, isActive: value === true })
                      }
                    />
                    <span className='text-sm font-medium'>Active</span>
                  </label>
                </div>

                <div className='flex flex-wrap gap-3'>
                  <Button onClick={() => void handleUpdate()} isLoading={updateMutation.isPending}>
                    Save Assignment
                  </Button>
                  <Button
                    variant='destructive'
                    onClick={() => void deleteMutation.mutateAsync(selectedAssignment.id)}
                    isLoading={deleteMutation.isPending}
                  >
                    Remove Assignment
                  </Button>
                </div>
              </>
            )}
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
