"use client";

import * as React from "react";

import { Upload } from "lucide-react";
import { Controller, type UseFormReturn } from "react-hook-form";

import {
  PHONE_COUNTRIES,
  TIMEZONES,
} from "@/app/dashboard/customers/_components/customer-form/constants";
import { FormField } from "@/components/form/form-field";
import { Button } from "@/components/ui/button";
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/ui/input-group";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

/** The fields this section reads and writes; the create and edit forms both contain them. */
export type CustomerProfileValues = {
  first_name: string;
  last_name: string;
  short_name: string;
  phone_country: string;
  phone: string;
  email: string;
  confirm_email: string;
  password: string;
  con_password: string;
  timezone: string;
  company_name: string;
  registration_number: string;
  company_address: string;
};

const PASSWORD_UNCHANGED_HINT = "Leave blank to keep the current password.";

function sanitizePhone(value: string) {
  return value.replace(/\D/g, "");
}

type CustomerProfileSectionProps<T extends CustomerProfileValues> = {
  form: UseFormReturn<T>;
  shortNameChecking: boolean;
  /** The Account ID field: editable on create, read-only on edit. */
  accountIdField: React.ReactNode;
  /** Create requires a password; edit leaves it blank to keep the current one. */
  passwordRequired: boolean;
};

/**
 * Personal, contact and company fields shared by the tenant customer create and edit forms.
 * Rendered as one card; field order and markup are identical in both forms.
 */
export function CustomerProfileSection<T extends CustomerProfileValues>({
  form: formProp,
  shortNameChecking,
  accountIdField,
  passwordRequired,
}: CustomerProfileSectionProps<T>) {
  // The wider create/edit form types are not assignable to the shared subset (react-hook-form is
  // invariant in its field-values type), so the narrowing happens once, here.
  const form = formProp as unknown as UseFormReturn<CustomerProfileValues>;
  const errors = form.formState.errors;
  const [profileName, setProfileName] = React.useState("");
  const profileInput = React.useRef<HTMLInputElement>(null);

  return (
      <section className="grid gap-4 rounded-lg border bg-card p-4 md:grid-cols-2 xl:grid-cols-3">
        <FormField
          label="First Name"
          htmlFor="first_name"
          required
          error={errors.first_name}
        >
          <Input
            id="first_name"
            placeholder="First Name"
            {...form.register("first_name")}
          />
        </FormField>
        <FormField label="Last Name" htmlFor="last_name">
          <Input
            id="last_name"
            placeholder="Last Name"
            {...form.register("last_name")}
          />
        </FormField>
        <FormField
          label="Short Name"
          htmlFor="short_name"
          error={errors.short_name}
          description={
            shortNameChecking ? "Checking availability…" : undefined
          }
        >
          <Input
            id="short_name"
            placeholder="Short Name"
            {...form.register("short_name")}
          />
        </FormField>
        <FormField label="Profile Image" htmlFor="profile_image">
          <input
            ref={profileInput}
            id="profile_image"
            type="file"
            accept=".png,.jpg,.jpeg"
            className="sr-only"
            onChange={(event) =>
              setProfileName(event.target.files?.[0]?.name ?? "")
            }
          />
          <Button
            type="button"
            variant="outline"
            className="w-full justify-start"
            onClick={() => profileInput.current?.click()}
          >
            <Upload />
            {profileName || "Browse"}
          </Button>
        </FormField>

        <FormField
          label="Mobile Number"
          htmlFor="phone"
          required
          error={errors.phone}
        >
          <Controller
            name="phone"
            control={form.control}
            render={({ field: phoneField }) => (
              <InputGroup>
                <InputGroupAddon align="inline-start" className="border-r">
                  <Controller
                    name="phone_country"
                    control={form.control}
                    render={({ field }) => (
                      <Select
                        value={field.value}
                        onValueChange={field.onChange}
                      >
                        <SelectTrigger className="h-7 w-28 border-0 bg-transparent shadow-none">
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          {PHONE_COUNTRIES.map((country) => (
                            <SelectItem
                              key={country.code}
                              value={country.code}
                            >
                              {country.flag} {country.dial}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    )}
                  />
                </InputGroupAddon>
                <InputGroupInput
                  id="phone"
                  placeholder="e.g. 6 701 5757"
                  value={phoneField.value}
                  onChange={(event) =>
                    phoneField.onChange(sanitizePhone(event.target.value))
                  }
                />
              </InputGroup>
            )}
          />
        </FormField>

        {accountIdField}

        <FormField
          label="E-Mail Address"
          htmlFor="email"
          required
          error={errors.email}
        >
          <Input
            id="email"
            type="email"
            placeholder="E-mail Address"
            autoComplete="email"
            {...form.register("email")}
          />
        </FormField>
        <FormField
          label="Confirm Email"
          htmlFor="confirm_email"
          required
          error={errors.confirm_email}
          className="xl:col-span-2"
        >
          <Input
            id="confirm_email"
            type="email"
            placeholder="Confirm Email"
            autoComplete="email"
            {...form.register("confirm_email")}
          />
        </FormField>

        <FormField
          label="Enter Password"
          htmlFor="password"
          required={passwordRequired}
          error={errors.password}
          description={passwordRequired ? undefined : PASSWORD_UNCHANGED_HINT}
        >
          <Input
            id="password"
            type="password"
            placeholder="Enter Password"
            autoComplete="new-password"
            {...form.register("password")}
          />
        </FormField>
        <FormField
          label="Confirm Password"
          htmlFor="con_password"
          required={passwordRequired}
          error={errors.con_password}
        >
          <Input
            id="con_password"
            type="password"
            placeholder="Confirm Password"
            autoComplete="new-password"
            {...form.register("con_password")}
          />
        </FormField>
        <FormField
          label="Timezone"
          htmlFor="timezone"
          required
          error={errors.timezone}
        >
          <Controller
            name="timezone"
            control={form.control}
            render={({ field }) => (
              <Select value={field.value} onValueChange={field.onChange}>
                <SelectTrigger id="timezone">
                  <SelectValue placeholder="Select timezone" />
                </SelectTrigger>
                <SelectContent>
                  {TIMEZONES.map((timezone) => (
                    <SelectItem key={timezone.value} value={timezone.value}>
                      {timezone.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            )}
          />
        </FormField>

        <FormField label="Company/Business Name" htmlFor="company_name">
          <Input
            id="company_name"
            placeholder="Company/Business Name"
            {...form.register("company_name")}
          />
        </FormField>
        <FormField
          label="Registration Number"
          htmlFor="registration_number"
          className="xl:col-span-2"
        >
          <Input
            id="registration_number"
            placeholder="Registration Number"
            {...form.register("registration_number")}
          />
        </FormField>
        <FormField
          label="Business Address Line"
          htmlFor="company_address"
          className="md:col-span-2 xl:col-span-3"
        >
          <Input
            id="company_address"
            placeholder="Business Address Line 1"
            {...form.register("company_address")}
          />
        </FormField>
      </section>
  );
}
