"use client"

import { useRouter } from "@/i18n/navigation"
import { z } from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
import { type Control, type FieldPath, useForm } from "react-hook-form"
import { useTranslations } from "next-intl"

import { FormSection } from "@/components/form-section"
import { PageHeader } from "@/components/page-header"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { Textarea } from "@/components/ui/textarea"
import {
  getPlanConfigurationById,
  type PlanConfigurationRecord,
  type PlanFeatureDefinition,
  planFeatureGroups,
} from "@/lib/plan-configurations"

const booleanFeatureSchema = z.object({
  active: z.boolean(),
  shownByDefault: z.boolean(),
})

const numericFeatureSchema = z.object({
  value: z.number().int().min(0, "Value must be 0 or greater."),
  shownByDefault: z.boolean(),
})

function buildFeatureGroupSchema(definitions: readonly PlanFeatureDefinition[]) {
  return z.object(
    Object.fromEntries(
      definitions.map((definition) => [
        definition.key,
        definition.kind === "number" ? numericFeatureSchema : booleanFeatureSchema,
      ])
    )
  )
}

const planConfigurationSchema = z.object({
  code: z.string().min(2, "Code is required."),
  name: z.string().min(2, "Name is required."),
  description: z.string().min(10, "Description is required."),
  monthlyAmount: z.number().min(0, "Monthly amount must be 0 or greater."),
  yearlyAmount: z.number().min(0, "Yearly amount must be 0 or greater."),
  status: z.enum(["active", "inactive"]),
  trial: z.object({
    allowTrial: z.boolean(),
    trialDays: z.number().int().min(0, "Value must be 0 or greater."),
    warningExpireDays: z.number().int().min(0, "Value must be 0 or greater."),
  }).superRefine((data, ctx) => {
    if (!data.allowTrial) return

    if (data.trialDays <= 0) {
      ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["trialDays"], message: "Trial days must be greater than 0." })
    }
    if (data.warningExpireDays <= 0) {
      ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["warningExpireDays"], message: "Warning expire days must be greater than 0." })
    }
  }),
  basicFeatures: buildFeatureGroupSchema(planFeatureGroups.basicFeatures),
  salesAndMarketing: buildFeatureGroupSchema(planFeatureGroups.salesAndMarketing),
  paymentMethods: buildFeatureGroupSchema(planFeatureGroups.paymentMethods),
  technicalSupport: buildFeatureGroupSchema(planFeatureGroups.technicalSupport),
})

type PlanConfigurationFormValues = z.infer<typeof planConfigurationSchema>
type PlanFeatureGroupKey = keyof Pick<
  PlanConfigurationFormValues,
  "basicFeatures" | "salesAndMarketing" | "paymentMethods" | "technicalSupport"
>
type FeatureSectionConfig = {
  groupKey: PlanFeatureGroupKey
  titleKey: `sections.${PlanFeatureGroupKey}`
  featurePrefix: PlanFeatureGroupKey
  definitions: readonly PlanFeatureDefinition[]
}

function fieldPath(path: string) {
  return path as FieldPath<PlanConfigurationFormValues>
}

const featureSections: readonly FeatureSectionConfig[] = [
  {
    groupKey: "basicFeatures",
    titleKey: "sections.basicFeatures",
    featurePrefix: "basicFeatures",
    definitions: planFeatureGroups.basicFeatures,
  },
  {
    groupKey: "salesAndMarketing",
    titleKey: "sections.salesAndMarketing",
    featurePrefix: "salesAndMarketing",
    definitions: planFeatureGroups.salesAndMarketing,
  },
  {
    groupKey: "paymentMethods",
    titleKey: "sections.paymentMethods",
    featurePrefix: "paymentMethods",
    definitions: planFeatureGroups.paymentMethods,
  },
  {
    groupKey: "technicalSupport",
    titleKey: "sections.technicalSupport",
    featurePrefix: "technicalSupport",
    definitions: planFeatureGroups.technicalSupport,
  },
]

function createFeatureGroupDefaults(definitions: readonly PlanFeatureDefinition[]) {
  return Object.fromEntries(
    definitions.map((definition) => [
      definition.key,
      definition.kind === "number"
        ? { value: 0, shownByDefault: false }
        : { active: false, shownByDefault: false },
    ])
  )
}

function cloneFeatureGroup(
  group: PlanConfigurationRecord["basicFeatures"] | undefined,
  definitions: readonly PlanFeatureDefinition[]
) {
  if (!group) {
    return createFeatureGroupDefaults(definitions)
  }

  return Object.fromEntries(
    definitions.map((definition) => {
      const value = group[definition.key]
      return [
        definition.key,
        definition.kind === "number"
          ? {
            value:
              value && "value" in value && Number.isFinite(value.value) ? value.value : 0,
            shownByDefault: Boolean(value?.shownByDefault),
          }
          : {
            active: Boolean(value && "active" in value ? value.active : false),
            shownByDefault: Boolean(value?.shownByDefault),
          },
      ]
    })
  )
}

function getDefaultValues(id?: string): PlanConfigurationFormValues {
  const record = getPlanConfigurationById(id)

  if (!record) {
    return {
      code: "",
      name: "",
      description: "",
      monthlyAmount: 0,
      yearlyAmount: 0,
      status: "active",
      trial: {
        allowTrial: false,
        trialDays: 14,
        warningExpireDays: 2,
      },
      basicFeatures: createFeatureGroupDefaults(planFeatureGroups.basicFeatures),
      salesAndMarketing: createFeatureGroupDefaults(planFeatureGroups.salesAndMarketing),
      paymentMethods: createFeatureGroupDefaults(planFeatureGroups.paymentMethods),
      technicalSupport: createFeatureGroupDefaults(planFeatureGroups.technicalSupport),
    }
  }

  return {
    code: record.code,
    name: record.name,
    description: record.description,
    monthlyAmount: record.monthlyAmount,
    yearlyAmount: record.yearlyAmount,
    status: record.status,
    trial: record.trial
      ? { ...record.trial }
      : { allowTrial: false, trialDays: 14, warningExpireDays: 2 },
    basicFeatures: cloneFeatureGroup(record.basicFeatures, planFeatureGroups.basicFeatures),
    salesAndMarketing: cloneFeatureGroup(
      record.salesAndMarketing,
      planFeatureGroups.salesAndMarketing
    ),
    paymentMethods: cloneFeatureGroup(record.paymentMethods, planFeatureGroups.paymentMethods),
    technicalSupport: cloneFeatureGroup(
      record.technicalSupport,
      planFeatureGroups.technicalSupport
    ),
  }
}

function BooleanFeatureRow({
  control,
  groupKey,
  featureKey,
  label,
  activeLabel,
  shownByDefaultLabel,
}: {
  control: Control<PlanConfigurationFormValues>
  groupKey: PlanFeatureGroupKey
  featureKey: string
  label: string
  activeLabel: string
  shownByDefaultLabel: string
}) {
  return (
    <div className="md:items-center gap-4 grid md:grid-cols-[minmax(0,1fr)_200px_220px] p-4 border rounded-lg">
      <div className="font-medium">{label}</div>
      <FormField
        control={control}
        name={fieldPath(`${groupKey}.${featureKey}.active`)}
        render={({ field }) => (
          <FormItem className="flex items-center gap-2 space-y-0">
            <FormControl>
              <Checkbox
                checked={Boolean(field.value)}
                onCheckedChange={(checked) => field.onChange(checked === true)}
              />
            </FormControl>
            <FormLabel className="font-normal">{activeLabel}</FormLabel>
          </FormItem>
        )}
      />
      <FormField
        control={control}
        name={fieldPath(`${groupKey}.${featureKey}.shownByDefault`)}
        render={({ field }) => (
          <FormItem className="flex items-center gap-2 space-y-0">
            <FormControl>
              <Checkbox
                checked={Boolean(field.value)}
                onCheckedChange={(checked) => field.onChange(checked === true)}
              />
            </FormControl>
            <FormLabel className="font-normal">{shownByDefaultLabel}</FormLabel>
          </FormItem>
        )}
      />
    </div>
  )
}

function NumericFeatureRow({
  control,
  groupKey,
  featureKey,
  label,
  valueLabel,
  shownByDefaultLabel,
}: {
  control: Control<PlanConfigurationFormValues>
  groupKey: PlanFeatureGroupKey
  featureKey: string
  label: string
  valueLabel: string
  shownByDefaultLabel: string
}) {
  return (
    <div className="md:items-center gap-4 grid md:grid-cols-[minmax(0,1fr)_220px_220px] p-4 border rounded-lg">
      <div className="font-medium">{label}</div>
      <FormField
        control={control}
        name={fieldPath(`${groupKey}.${featureKey}.value`)}
        render={({ field }) => (
          <FormItem>
            <FormLabel>{valueLabel}</FormLabel>
            <FormControl>
              <Input
                type="number"
                min={0}
                value={typeof field.value === "number" ? field.value : 0}
                onChange={(event) => field.onChange(event.target.valueAsNumber)}
              />
            </FormControl>
            <FormMessage />
          </FormItem>
        )}
      />
      <FormField
        control={control}
        name={fieldPath(`${groupKey}.${featureKey}.shownByDefault`)}
        render={({ field }) => (
          <FormItem className="flex items-center self-end gap-2 space-y-0 md:pb-2">
            <FormControl>
              <Checkbox
                checked={Boolean(field.value)}
                onCheckedChange={(checked) => field.onChange(checked === true)}
              />
            </FormControl>
            <FormLabel className="font-normal">{shownByDefaultLabel}</FormLabel>
          </FormItem>
        )}
      />
    </div>
  )
}

function FeatureGroupSection({
  control,
  groupKey,
  title,
  definitions,
  featurePrefix,
  activeLabel,
  shownByDefaultLabel,
  valueLabel,
}: {
  control: Control<PlanConfigurationFormValues>
  groupKey: PlanFeatureGroupKey
  title: string
  definitions: readonly PlanFeatureDefinition[]
  featurePrefix: string
  activeLabel: string
  shownByDefaultLabel: string
  valueLabel: string
}) {
  const tEditor = useTranslations("Plans.Editor")

  return (
    <FormSection title={title}>
      <div className="gap-4 grid">
        {definitions.map((definition) => {
          const label = tEditor(`features.${featurePrefix}.${definition.key}`)

          if (definition.kind === "number") {
            return (
              <NumericFeatureRow
                key={definition.key}
                control={control}
                groupKey={groupKey}
                featureKey={definition.key}
                label={label}
                valueLabel={valueLabel}
                shownByDefaultLabel={shownByDefaultLabel}
              />
            )
          }

          return (
            <BooleanFeatureRow
              key={definition.key}
              control={control}
              groupKey={groupKey}
              featureKey={definition.key}
              label={label}
              activeLabel={activeLabel}
              shownByDefaultLabel={shownByDefaultLabel}
            />
          )
        })}
      </div>
    </FormSection>
  )
}

export function PlanConfigurationEditor({
  mode,
  id,
}: {
  mode: "create" | "edit"
  id?: string
}) {
  const tEditor = useTranslations("Plans.Editor")
  const tCreate = useTranslations("Plans.Create")
  const tEdit = useTranslations("Plans.Edit")
  const tc = useTranslations("Common")
  const router = useRouter()

  const form = useForm<PlanConfigurationFormValues>({
    resolver: zodResolver(planConfigurationSchema),
    defaultValues: getDefaultValues(id),
  })

  const allowTrial = form.watch("trial.allowTrial")

  return (
    <div className="flex flex-col gap-4 md:gap-6 py-4 md:py-6">
      <PageHeader
        title={mode === "create" ? tCreate("title") : tEdit("title", { id: id ?? "" })}
        actions={
          <Button variant="outline" type="button" onClick={() => router.back()}>
            {tc("actions.back")}
          </Button>
        }
      />

      <Form {...form}>
        <form className="gap-6 grid" onSubmit={form.handleSubmit(() => { })}>
          <FormField
            control={form.control}
            name="status"
            render={({ field }) => (
              <FormItem className="flex justify-between items-center mx-4 lg:mx-6 p-4 border rounded-lg">
                <div className="gap-1 grid">
                  <FormLabel>{tEditor("labels.status")}</FormLabel>
                  <div className="text-muted-foreground text-sm">
                    {field.value === "active"
                      ? tEditor("controls.active")
                      : tEditor("controls.inactive")}
                  </div>
                </div>
                <FormControl>
                  <Checkbox
                    checked={field.value === "active"}
                    onCheckedChange={(checked) =>
                      field.onChange(checked === true ? "active" : "inactive")
                    }
                    aria-label={tEditor("labels.status")}
                  />
                </FormControl>
              </FormItem>
            )}
          />

          <FormSection title={tEditor("sections.basicInformation")}>
            <div className="gap-4 grid md:grid-cols-2">
              <FormField
                control={form.control}
                name="code"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>{tEditor("labels.code")}</FormLabel>
                    <FormControl>
                      <Input placeholder={tEditor("placeholders.code")} {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name="name"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>{tEditor("labels.name")}</FormLabel>
                    <FormControl>
                      <Input placeholder={tEditor("placeholders.name")} {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name="description"
                render={({ field }) => (
                  <FormItem className="md:col-span-2">
                    <FormLabel>{tEditor("labels.description")}</FormLabel>
                    <FormControl>
                      <Textarea rows={4} placeholder={tEditor("placeholders.description")} {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>
          </FormSection>

          <FormSection title={tEditor("sections.pricing")}>
            <div className="gap-4 grid md:grid-cols-2">
              <FormField
                control={form.control}
                name="monthlyAmount"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>{tEditor("labels.monthlyAmount")}</FormLabel>
                    <FormControl>
                      <Input
                        type="number"
                        min={0}
                        step="0.01"
                        value={Number.isFinite(field.value) ? field.value : 0}
                        onChange={(event) => field.onChange(event.target.valueAsNumber)}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name="yearlyAmount"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>{tEditor("labels.yearlyAmount")}</FormLabel>
                    <FormControl>
                      <Input
                        type="number"
                        min={0}
                        step="0.01"
                        value={Number.isFinite(field.value) ? field.value : 0}
                        onChange={(event) => field.onChange(event.target.valueAsNumber)}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>
          </FormSection>

          <FormSection title={tEditor("sections.trial")}>
            <div className="gap-4 grid">
              <FormField
                control={form.control}
                name="trial.allowTrial"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>{tEditor("labels.allowTrial")}</FormLabel>
                    <Select
                      value={field.value ? "yes" : "no"}
                      onValueChange={(value) => field.onChange(value === "yes")}
                    >
                      <FormControl>
                        <SelectTrigger>
                          <SelectValue placeholder={tEditor("labels.allowTrial")} />
                        </SelectTrigger>
                      </FormControl>
                      <SelectContent>
                        <SelectItem value="yes">{tEditor("controls.yes")}</SelectItem>
                        <SelectItem value="no">{tEditor("controls.no")}</SelectItem>
                      </SelectContent>
                    </Select>
                    <FormMessage />
                  </FormItem>
                )}
              />
              {allowTrial && (
                <>
                  <FormField
                    control={form.control}
                    name="trial.trialDays"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>
                          {tEditor("labels.trialDays")} <span className="text-destructive">*</span>
                        </FormLabel>
                        <FormControl>
                          <Input
                            type="number"
                            min={0}
                            value={Number.isFinite(field.value) ? field.value : 0}
                            onChange={(event) => field.onChange(event.target.valueAsNumber)}
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name="trial.warningExpireDays"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>
                          {tEditor("labels.warningExpireDays")} <span className="text-destructive">*</span>
                        </FormLabel>
                        <FormControl>
                          <Input
                            type="number"
                            min={0}
                            value={Number.isFinite(field.value) ? field.value : 0}
                            onChange={(event) => field.onChange(event.target.valueAsNumber)}
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </>
              )}
            </div>
          </FormSection>

          {featureSections.map((section) => (
            <FeatureGroupSection
              key={section.groupKey}
              control={form.control}
              groupKey={section.groupKey}
              title={tEditor(section.titleKey)}
              definitions={section.definitions}
              featurePrefix={section.featurePrefix}
              activeLabel={tEditor("controls.active")}
              shownByDefaultLabel={tEditor("controls.shownByDefault")}
              valueLabel={tEditor("controls.value")}
            />
          ))}

          <div className="px-4 lg:px-6">
            <div className="flex justify-end items-center gap-2">
              <Button variant="outline" type="button" onClick={() => router.back()}>
                {tc("actions.cancel")}
              </Button>
              <Button type="submit">
                {mode === "create" ? tc("actions.create") : tc("actions.saveChanges")}
              </Button>
            </div>
          </div>
        </form>
      </Form>
    </div>
  )
}
