"use client";

import { useState } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { Plus, Pencil, Trophy, XCircle } from "lucide-react";
import {
  Button,
  Dialog,
  Drawer,
  Input,
  FormField,
  Select,
  EmptyState,
  ConfirmDialog,
} from "@/components/ds";
import { crmApi } from "@/modules/crm/services/crm-api";
import { useTenantId } from "@/hooks/useTenantId";
import { CrmTablePage, CrmStatusChip } from "@/modules/crm/design-system";
import { CrmBreadcrumbs } from "@/modules/crm/components/CrmBreadcrumbs";
import { CrmPageLoader, CrmPageError } from "@/modules/crm/pages/shared";
import type { Opportunity, Pipeline, PipelineStage } from "@/modules/crm/types";

const createSchema = z.object({
  title: z.string().min(1, "عنوان الزامی است"),
  pipeline_id: z.string().uuid(),
  stage_id: z.string().uuid(),
  amount: z.string().default("0"),
  probability: z.number().min(0).max(100).default(0),
  priority: z.enum(["low", "medium", "high", "urgent"]).default("medium"),
  expected_close_date: z.string().optional(),
  description: z.string().optional(),
});

export default function DealsPage() {
  const { tenantId } = useTenantId();
  const qc = useQueryClient();
  const [createOpen, setCreateOpen] = useState(false);
  const [editRow, setEditRow] = useState<Opportunity | null>(null);
  const [winId, setWinId] = useState<string | null>(null);
  const [loseId, setLoseId] = useState<string | null>(null);
  const [page, setPage] = useState(1);

  const pipelinesQ = useQuery({
    queryKey: ["crm", tenantId, "pipelines"],
    queryFn: () => crmApi.pipelines.list(tenantId!, { page: 1, page_size: 100 }),
    enabled: !!tenantId,
  });

  const listQ = useQuery({
    queryKey: ["crm", tenantId, "opportunities"],
    queryFn: () => crmApi.opportunities.list(tenantId!, { page: 1, page_size: 500 }),
    enabled: !!tenantId,
  });

  const stagesQ = useQuery({
    queryKey: ["crm", tenantId, "all-stages"],
    queryFn: async () => {
      const pipelines = pipelinesQ.data ?? [];
      const stages: PipelineStage[] = [];
      for (const p of pipelines) {
        const s = await crmApi.pipelines.stages(tenantId!, p.id, { page: 1, page_size: 100 });
        stages.push(...s);
      }
      return stages;
    },
    enabled: !!tenantId && !!pipelinesQ.data?.length,
  });

  const form = useForm({
    resolver: zodResolver(createSchema),
    defaultValues: {
      title: "",
      pipeline_id: "",
      stage_id: "",
      amount: "0",
      probability: 0,
      priority: "medium" as const,
      description: "",
    },
  });

  const editForm = useForm({
    resolver: zodResolver(createSchema.partial()),
  });

  const pipelineId = form.watch("pipeline_id");
  const stageOptions =
    stagesQ.data?.filter((s) => s.pipeline_id === pipelineId) ?? [];

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ["crm", tenantId, "opportunities"] });
  };

  const createM = useMutation({
    mutationFn: (d: Record<string, unknown>) =>
      crmApi.opportunities.create(tenantId!, { ...d, name: d.title }),
    onSuccess: async () => {
      toast.success("معامله ایجاد شد");
      setCreateOpen(false);
      form.reset();
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const updateM = useMutation({
    mutationFn: (d: Record<string, unknown>) =>
      crmApi.opportunities.update(tenantId!, editRow!.id, d),
    onSuccess: async () => {
      toast.success("معامله به‌روز شد");
      setEditRow(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const winM = useMutation({
    mutationFn: (id: string) => crmApi.opportunities.win(tenantId!, id),
    onSuccess: async () => {
      toast.success("معامله برنده شد");
      setWinId(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const loseM = useMutation({
    mutationFn: (id: string) =>
      crmApi.opportunities.lose(tenantId!, id, { reason_id: null }),
    onSuccess: async () => {
      toast.success("معامله باخته شد");
      setLoseId(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const stageName = (id: string) =>
    stagesQ.data?.find((s) => s.id === id)?.name ?? id.slice(0, 8);

  if (!tenantId || listQ.isLoading || pipelinesQ.isLoading) return <CrmPageLoader />;
  if (listQ.error) return <CrmPageError error={listQ.error} onRetry={() => listQ.refetch()} />;

  const pipelines = pipelinesQ.data ?? [];

  return (
    <div>
      <CrmTablePage
        breadcrumbs={<CrmBreadcrumbs items={[{ label: "معاملات" }]} />}
        title="معاملات"
        description="فرصت‌های فروش (Opportunities) — قیف، مبلغ، احتمال و بستن معامله."
        columns={[
          { key: "opportunity_number", header: "شماره" },
          { key: "title", header: "عنوان" },
          {
            key: "stage_id",
            header: "مرحله",
            render: (r) => stageName(String(r.stage_id)),
          },
          { key: "amount", header: "مبلغ" },
          { key: "probability", header: "احتمال %" },
          {
            key: "status",
            header: "وضعیت",
            render: (r) => (
              <CrmStatusChip status={String(r.status)} domain="opportunity" />
            ),
          },
          {
            key: "actions",
            header: "عملیات",
            searchable: false,
            render: (r) => (
              <div className="flex gap-1">
                <Button
                  variant="ghost"
                  size="icon"
                  onClick={() => {
                    setEditRow(r as unknown as Opportunity);
                    editForm.reset({
                      title: String(r.title ?? r.name ?? ""),
                      amount: String(r.amount),
                      probability: Number(r.probability),
                      priority: String(r.priority) as "medium",
                    });
                  }}
                >
                  <Pencil className="h-4 w-4" />
                </Button>
                {r.status === "open" ? (
                  <>
                    <Button variant="ghost" size="icon" onClick={() => setWinId(String(r.id))}>
                      <Trophy className="h-4 w-4 text-emerald-600" />
                    </Button>
                    <Button variant="ghost" size="icon" onClick={() => setLoseId(String(r.id))}>
                      <XCircle className="h-4 w-4 text-red-600" />
                    </Button>
                  </>
                ) : null}
              </div>
            ),
          },
        ]}
        rows={(listQ.data ?? []) as unknown as Record<string, unknown>[]}
        page={page}
        pageSize={20}
        onPageChange={setPage}
        actions={
          <Button onClick={() => setCreateOpen(true)} disabled={!pipelines.length}>
            <Plus className="h-4 w-4" />
            معامله جدید
          </Button>
        }
        empty={
          <EmptyState
            title="معامله‌ای نیست"
            description={pipelines.length ? undefined : "ابتدا یک قیف فروش ایجاد کنید."}
            action={
              pipelines.length ? (
                <Button onClick={() => setCreateOpen(true)}>ایجاد معامله</Button>
              ) : undefined
            }
          />
        }
      />

      <Dialog open={createOpen} onClose={() => setCreateOpen(false)} title="معامله جدید">
        <form className="space-y-3" onSubmit={form.handleSubmit((d) => createM.mutate(d))}>
          <FormField label="عنوان">
            <Input {...form.register("title")} />
          </FormField>
          <FormField label="قیف">
            <Select {...form.register("pipeline_id")}>
              <option value="">انتخاب</option>
              {pipelines.map((p: Pipeline) => (
                <option key={p.id} value={p.id}>
                  {p.name}
                </option>
              ))}
            </Select>
          </FormField>
          <FormField label="مرحله">
            <Select {...form.register("stage_id")}>
              <option value="">انتخاب</option>
              {stageOptions.map((s) => (
                <option key={s.id} value={s.id}>
                  {s.name}
                </option>
              ))}
            </Select>
          </FormField>
          <FormField label="مبلغ">
            <Input {...form.register("amount")} />
          </FormField>
          <FormField label="احتمال (%)">
            <Input type="number" {...form.register("probability", { valueAsNumber: true })} />
          </FormField>
          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => setCreateOpen(false)}>
              انصراف
            </Button>
            <Button type="submit" disabled={createM.isPending}>
              ذخیره
            </Button>
          </div>
        </form>
      </Dialog>

      <Drawer open={!!editRow} onClose={() => setEditRow(null)} title="ویرایش معامله">
        <form className="space-y-3" onSubmit={editForm.handleSubmit((d) => updateM.mutate(d))}>
          <FormField label="عنوان">
            <Input {...editForm.register("title")} />
          </FormField>
          <FormField label="مبلغ">
            <Input {...editForm.register("amount")} />
          </FormField>
          <FormField label="احتمال">
            <Input type="number" {...editForm.register("probability", { valueAsNumber: true })} />
          </FormField>
          <Button type="submit" disabled={updateM.isPending}>
            به‌روزرسانی
          </Button>
        </form>
      </Drawer>

      <ConfirmDialog
        open={!!winId}
        onClose={() => setWinId(null)}
        onConfirm={() => winId && winM.mutate(winId)}
        title="برنده شدن معامله"
        description="وضعیت معامله به برنده تغییر می‌کند."
        confirmLabel="تأیید برنده"
        loading={winM.isPending}
      />
      <ConfirmDialog
        open={!!loseId}
        onClose={() => setLoseId(null)}
        onConfirm={() => loseId && loseM.mutate(loseId)}
        title="باخت معامله"
        description="وضعیت معامله به باخته تغییر می‌کند."
        confirmLabel="تأیید باخت"
        loading={loseM.isPending}
        danger
      />
    </div>
  );
}
