'use client';

import * as React from 'react';
import { useParams, useRouter } from 'next/navigation';
import {
  assignRoleToUser,
  fetchRoles,
  unassignRoleFromUser,
} from '@/modules/Roles/apis/roles.apis';
import { fetchUserById } from '@/network/apis/dashboard/userManagment/users/users.apis';
import { UserModel } from '@/utils/types/User';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { UserSubscriptions } from '../UserSubscriptions/UserSubscriptions';
import { AssignSubscriptionDialog } from '../UserSubscriptions/AssignSubscriptionDialog';
import { UserBalanceHistory } from '../UserBalanceHistory/UserBalanceHistory';
import axios from '@/network/axios';

type BalanceLastAddition = {
  amount: number;
  balance_after: number;
  date: string;
  action: string;
};

type BalanceEntry = {
  type_balance: number;
  label: string;
  current_balance: number;
  total_added: number;
  total_used: number;
  last_addition: BalanceLastAddition | null;
};

type BalanceSummaryResponse = {
  user_id: number;
  user_name: string;
  email: string;
  balances: BalanceEntry[];
};

type Role = { id: number; name: string; name_ar: string };

export default function UserDetails() {
  const router = useRouter();
  const params = useParams();
  const id = params?.id as string | undefined;
  const queryClient = useQueryClient();

  const {
    data: userDetails,
    isLoading,
    isError,
    error,
  } = useQuery({
    queryKey: ['user_details', id],
    queryFn: async () => {
      if (!id) return;
      const response = await fetchUserById(id.toString());
      return response;
    },
    enabled: !!id,
  });

  const { data: balanceSummary } = useQuery({
    queryKey: ['balance-summary', id],
    queryFn: async () => {
      const res = await axios.get<{ status: boolean; data: BalanceSummaryResponse }>(
        '/dashboard/balance/summary',
        { params: { user_id: id } },
      );
      return res.data.data;
    },
    enabled: !!id,
    staleTime: 30_000,
  });

  const balanceByType = React.useMemo(() => {
    const map: Record<number, BalanceEntry> = {};
    balanceSummary?.balances?.forEach((b) => {
      map[b.type_balance] = b;
    });
    return map;
  }, [balanceSummary]);

  const [openAssign, setOpenAssign] = React.useState(false);
  const [openAssignSub, setOpenAssignSub] = React.useState(false);
  const [selectedRoleName, setSelectedRoleName] = React.useState<string>('');

  const { data: rolesList, isLoading: isRolesLoading } = useQuery({
    queryKey: ['roles_list'],
    queryFn: async () => {
      const res = await fetchRoles();
      return res;
    },
    enabled: openAssign,
  });

  const assignMutation = useMutation({
    mutationFn: async () => {
      if (!id || !selectedRoleName) throw new Error('Select a role first');
      await assignRoleToUser(String(id), selectedRoleName);
    },
    onSuccess: () => {
      setOpenAssign(false);
      setSelectedRoleName('');
      queryClient.invalidateQueries({ queryKey: ['user_details', id] });
    },
  });

  const unassignMutation = useMutation({
    mutationFn: async (roleName: string) => {
      if (!id) throw new Error('Missing user id');
      await unassignRoleFromUser(String(id), roleName);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['user_details', id] });
    },
  });

  if (!id)
    return (
      <div className="p-6 text-sm text-slate-600">No user id provided.</div>
    );
  if (isLoading)
    return <div className="p-6 text-sm text-slate-600">Loading user…</div>;
  if (isError) {
    return (
      <div className="p-6 text-sm text-red-600">
        Failed to load user: {(error as Error)?.message ?? 'Unknown error'}
      </div>
    );
  }

  const user: UserModel | undefined = userDetails;
  if (!user)
    return <div className="p-6 text-sm text-slate-600">User not found.</div>;

  const fullName =
    `${user.first_name ?? ''} ${user.last_name ?? ''}`.trim() || '-';

  return (
    <div className="w-full max-w-4xl mx-auto p-6 space-y-6">
      <div className="mb-2 flex items-start justify-between gap-3">
        <div>
          <h2 className="text-xl font-semibold">{fullName}</h2>
          <p className="text-slate-500 text-sm">{user.email}</p>
        </div>
        <div className="flex gap-2">
          <Button onClick={() => router.push(`/users/add/${id}`)}>Edit</Button>
          <Button
            variant="outline"
            onClick={() => setOpenAssign(true)}
            disabled={assignMutation.isPending}
          >
            Assign Role
          </Button>
          <Button
            variant="outline"
            onClick={() => setOpenAssignSub(true)}
          >
            Assign Subscription
          </Button>
        </div>
      </div>

      <div className="rounded-2xl border border-slate-200 bg-white shadow-sm">
        <div className="p-4 sm:p-6 grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
          <div className="space-y-2">
            <div>
              <span className="text-slate-500">First Name:</span>{' '}
              {user.first_name || '-'}
            </div>
            <div>
              <span className="text-slate-500">Last Name:</span>{' '}
              {user.last_name || '-'}
            </div>
            <div>
              <span className="text-slate-500">Brand:</span>{' '}
              {user.brand_name || '-'}
            </div>
            <div>
              <span className="text-slate-500">Phone:</span> {user.phone || '-'}
            </div>
            <div>
              <span className="text-slate-500">Country:</span>{' '}
              {user.country?.name || '-'}
            </div>
            <div>
              <span className="text-slate-500">Status:</span>{' '}
              {user.is_activated ? 'Active' : 'Inactive'}
            </div>
            <div>
              <span className="text-slate-500">Email Verified:</span>{' '}
              {user.email_verified ? 'Yes' : 'No'}
            </div>
            <div>
              <span className="text-slate-500">Profile ID:</span>{' '}
              {user.profile_id ?? '-'}
            </div>
          </div>
          <div className="space-y-2">
            <div>
              <span className="text-slate-500">Account Type:</span>{' '}
              {user.account_type}
            </div>
            <div>
              <span className="text-slate-500">Credit:</span> {user.credit}
            </div>
            <div>
              <span className="text-slate-500">Total Used Amount:</span>{' '}
              {user.total_used_amount}
            </div>
            <div>
              <span className="text-slate-500">Reports:</span> {user.reports}
            </div>
            <div>
              <span className="text-slate-500">PPTX Downloads:</span>{' '}
              {user.pptx_downloads}
            </div>
            <div>
              <span className="text-slate-500">Paid Subscription:</span>{' '}
              {user.is_paid_subscription ? 'Yes' : 'No'}
            </div>
            <div>
              <span className="text-slate-500">Paid Plan:</span>{' '}
              {user.paid_subscription ?? '-'}
            </div>
          </div>
        </div>
      </div>

      <div className="rounded-2xl border border-slate-200 bg-white shadow-sm">
        <div className="p-4 sm:p-6">
          <h3 className="text-sm font-semibold mb-4">Balance Summary</h3>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b">
                  {[
                    { label: 'Reports', typeId: 1 },
                    { label: 'Search', typeId: 2 },
                    { label: 'Social Listen.', typeId: 3 },
                    { label: 'Lookalike', typeId: 4 },
                    { label: 'Network', typeId: 5 },
                    { label: 'Campaign', typeId: 6 },
                    { label: 'Competitor', typeId: 7 },
                    { label: 'Phone Number', typeId: 8 },
                    { label: 'Media Plan', typeId: 9 },
                    { label: 'MP Creators', typeId: 10 },
                    { label: 'WhatsApp', typeId: 11 },
                    { label: 'Collab. Req.', typeId: 12 },
                    { label: 'Rel. Lists', typeId: 13 },
                    { label: 'Inf./List', typeId: 14 },
                  ].map((col) => (
                    <th key={col.typeId} className="text-center px-3 py-2 font-semibold text-slate-700">
                      <div>{col.label}</div>
                      <div className="text-[10px] font-normal text-slate-400">added/current</div>
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                <tr>
                  {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((typeId) => {
                    const entry = balanceByType[typeId];
                    const fallbackKeys: Record<number, string> = {
                      1: 'requests_balance', 2: 'search_balance', 3: 'social_listening_balance',
                      4: 'lookalike_balance', 5: 'mynetwork_balance', 6: 'campaign_balance',
                      7: 'competitor_analysis_balance', 8: 'phone_number_balance',
                      9: 'media_plan_balance', 10: 'media_plan_creators_balance',
                    };
                    const fallbackVal = ((user as Record<string, unknown>)[fallbackKeys[typeId]] as number) ?? 0;

                    if (entry) {
                      const added = entry.total_added ?? 0;
                      const current = entry.current_balance ?? 0;
                      return (
                        <td key={typeId} className="text-center px-3 py-3 tabular-nums whitespace-nowrap">
                          <span className="text-slate-400">{Number(added).toLocaleString()}</span>
                          <span className="text-slate-300 mx-0.5">/</span>
                          <span className={`font-semibold ${current < added ? 'text-amber-600' : 'text-slate-800'}`}>
                            {Number(current).toLocaleString()}
                          </span>
                        </td>
                      );
                    }

                    return (
                      <td key={typeId} className="text-center px-3 py-3 tabular-nums whitespace-nowrap">
                        <span className="text-slate-400">0</span>
                        <span className="text-slate-300 mx-0.5">/</span>
                        <span className="font-semibold text-slate-800">
                          {Number(fallbackVal).toLocaleString()}
                        </span>
                      </td>
                    );
                  })}
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>

      <div className="rounded-2xl border border-slate-200 bg-white shadow-sm">
        <div className="p-4 sm:p-6 text-sm">
          <h3 className="text-sm font-semibold mb-3">Roles</h3>
          {user.roles?.length ? (
            <div className="space-y-4">
              {user.roles.map((r, idx) => (
                <div
                  key={`${r.name}-${idx}`}
                  className="rounded-xl border border-slate-200"
                >
                  <div className="px-4 py-2 bg-slate-50 rounded-t-xl flex items-center justify-between">
                    <div className="font-medium">{r.name}</div>
                    <Button
                      variant="destructive"
                      size="sm"
                      onClick={() => unassignMutation.mutate(r.name)}
                      disabled={unassignMutation.isPending}
                    >
                      {unassignMutation.isPending
                        ? 'Unassigning…'
                        : 'Unassign Role'}
                    </Button>
                  </div>
                  <div className="p-4">
                    <div className="text-slate-500 mb-2">Permissions</div>
                    {r.permissions?.length ? (
                      <ul className="list-disc ml-5 space-y-1">
                        {r.permissions.map((p, i) => (
                          <li key={`${r.name}-perm-${i}`}>{p}</li>
                        ))}
                      </ul>
                    ) : (
                      <div className="text-slate-500">No permissions</div>
                    )}
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="text-slate-500">No roles</div>
          )}
        </div>
      </div>

      <UserSubscriptions userId={id} />

      <AssignSubscriptionDialog
        userId={id}
        open={openAssignSub}
        onOpenChange={setOpenAssignSub}
      />

      <UserBalanceHistory userId={id} />

      <Dialog open={openAssign} onOpenChange={setOpenAssign}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Assign a role</DialogTitle>
          </DialogHeader>

          <div className="space-y-3">
            <label className="text-sm text-slate-600">Select Role</label>
            <Select
              value={selectedRoleName}
              onValueChange={(v) => setSelectedRoleName(v)}
              disabled={isRolesLoading || assignMutation.isPending}
            >
              <SelectTrigger>
                <SelectValue
                  placeholder={
                    isRolesLoading ? 'Loading roles…' : 'Choose a role'
                  }
                />
              </SelectTrigger>
              <SelectContent>
                {(rolesList as Role[] | undefined)?.map((r) => (
                  <SelectItem key={r.name} value={r.name}>
                    {r.name} — {r.name_ar}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <DialogFooter className="mt-4">
            <Button
              variant="outline"
              onClick={() => {
                setOpenAssign(false);
                setSelectedRoleName('');
              }}
            >
              Cancel
            </Button>
            <Button
              onClick={() => assignMutation.mutate()}
              disabled={!selectedRoleName || assignMutation.isPending}
            >
              {assignMutation.isPending ? 'Assigning…' : 'Assign'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
