"use client"

import * as React from "react"
import { useTranslations } from "next-intl"
import { z } from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { toast } from "sonner"

import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import { Skeleton } from "@/components/ui/skeleton"
import { ApiError } from "@/lib/api/errors"
import {
  assignSubscriptionToTenant,
  fetchSubscriptionPlans,
  type SubscriptionPlanOption,
} from "@/lib/api/subscription"

const schema = z.object({
  planId: z.string().min(1, "Please select a plan."),
  billingCycle: z.enum(["month", "year"]),
  duration: z.number().int().min(1, "Duration must be at least 1."),
  startDate: z.string().min(1, "Start date is required."),
})

type FormValues = z.infer<typeof schema>

function todayIsoDate(): string {
  return new Date().toISOString().slice(0, 10)
}

export function AssignPlanDialog({
  tenantId,
  trigger,
  open,
  onOpenChange,
  onSuccess,
}: {
  tenantId: string | null
  trigger?: React.ReactNode
  open?: boolean
  onOpenChange?: (open: boolean) => void
  onSuccess?: () => void
}) {
  const t = useTranslations("AssignPlanDialog")
  const tc = useTranslations("Common")

  const [plans, setPlans] = React.useState<SubscriptionPlanOption[]>([])
  const [plansLoading, setPlansLoading] = React.useState(false)
  const [submitting, setSubmitting] = React.useState(false)
  const [internalOpen, setInternalOpen] = React.useState(false)

  const isControlled = open !== undefined
  const dialogOpen = isControlled ? open : internalOpen

  const form = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: {
      planId: "",
      billingCycle: "month",
      duration: 12,
      startDate: todayIsoDate(),
    },
  })

  const { reset } = form

  React.useEffect(() => {
    if (!dialogOpen) return

    reset({
      planId: "",
      billingCycle: "month",
      duration: 12,
      startDate: todayIsoDate(),
    })

    let cancelled = false
    setPlansLoading(true)
    void fetchSubscriptionPlans()
      .then((items) => {
        if (!cancelled) setPlans(items)
      })
      .catch((e) => {
        if (!cancelled) {
          setPlans([])
          toast.error(e instanceof ApiError ? e.message : tc("api.errorFallback"))
        }
      })
      .finally(() => {
        if (!cancelled) setPlansLoading(false)
      })

    return () => {
      cancelled = true
    }
  }, [dialogOpen, reset, tc])

  return (
    <Dialog
      open={dialogOpen}
      onOpenChange={(next) => {
        if (!isControlled) setInternalOpen(next)
        onOpenChange?.(next)
      }}
    >
      {trigger ? <DialogTrigger asChild>{trigger}</DialogTrigger> : null}
      <DialogContent className="sm:max-w-md">
        <DialogHeader className="mb-4">
          <DialogTitle>{t("title")}</DialogTitle>
        </DialogHeader>

        <Form {...form}>
          <form
            className="gap-4 grid"
            onSubmit={form.handleSubmit(async (values) => {
              if (!tenantId) return

              setSubmitting(true)
              try {
                await assignSubscriptionToTenant(tenantId, {
                  plan_id: Number(values.planId),
                  period_unit: values.billingCycle,
                  duration: values.duration,
                  start_date: values.startDate,
                })
                toast.success(t("toast.assigned"))
                if (!isControlled) setInternalOpen(false)
                onOpenChange?.(false)
                onSuccess?.()
              } catch (e) {
                toast.error(
                  e instanceof ApiError ? e.message : tc("api.errorFallback")
                )
              } finally {
                setSubmitting(false)
              }
            })}
          >
            <FormField
              control={form.control}
              name="planId"
              render={({ field }) => (
                <FormItem className="mb-2">
                  <FormLabel>{t("planLabel")}</FormLabel>
                  <FormControl>
                    {plansLoading ? (
                      <div className="gap-2 grid">
                        <Skeleton className="h-10 w-full" />
                        <Skeleton className="h-10 w-full" />
                      </div>
                    ) : plans.length === 0 ? (
                      <p className="text-muted-foreground text-sm">{t("noPlans")}</p>
                    ) : (
                      <RadioGroup
                        value={field.value}
                        onValueChange={field.onChange}
                        className="flex flex-col gap-2 w-full"
                      >
                        {plans.map((plan) => (
                          <Label
                            key={plan.id}
                            htmlFor={`assign-plan-${plan.id}`}
                            className="flex cursor-pointer items-center gap-2 rounded-lg border border-input px-3 py-2"
                          >
                            <RadioGroupItem
                              id={`assign-plan-${plan.id}`}
                              value={String(plan.id)}
                            />
                            <span>{plan.name}</span>
                          </Label>
                        ))}
                      </RadioGroup>
                    )}
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="billingCycle"
              render={({ field }) => (
                <FormItem className="mb-2">
                  <FormLabel>{t("billingCycleLabel")}</FormLabel>
                  <FormControl>
                    <RadioGroup
                      value={field.value}
                      onValueChange={field.onChange}
                      className="flex w-full items-center gap-2"
                    >
                      <Label
                        htmlFor="assign-plan-month"
                        className="flex flex-1 cursor-pointer items-center justify-center gap-2 rounded-lg border border-input px-3 py-2"
                      >
                        <RadioGroupItem id="assign-plan-month" value="month" />
                        <span>{t("billing.month")}</span>
                      </Label>
                      <Label
                        htmlFor="assign-plan-year"
                        className="flex flex-1 cursor-pointer items-center justify-center gap-2 rounded-lg border border-input px-3 py-2"
                      >
                        <RadioGroupItem id="assign-plan-year" value="year" />
                        <span>{t("billing.year")}</span>
                      </Label>
                    </RadioGroup>
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <div className="gap-4 grid sm:grid-cols-2">
              <FormField
                control={form.control}
                name="duration"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>{t("durationLabel")}</FormLabel>
                    <FormControl>
                      <Input
                        type="number"
                        min={1}
                        name={field.name}
                        ref={field.ref}
                        value={field.value}
                        onBlur={field.onBlur}
                        onChange={(e) => field.onChange(Number(e.target.value))}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <FormField
                control={form.control}
                name="startDate"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>{t("startDateLabel")}</FormLabel>
                    <FormControl>
                      <Input type="date" {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>

            <div className="flex justify-end gap-2">
              <Button
                type="submit"
                disabled={
                  submitting || plansLoading || !tenantId || plans.length === 0
                }
              >
                {submitting ? tc("api.saving") : tc("actions.assign")}
              </Button>
            </div>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  )
}
