'use client';

import { Alert, Button, Checkbox, Field, Input, Select, Textarea } from '@/components/ui';
import { cn } from '@/lib/cn';
import {
  ACCESS_OPTIONS,
  COVERAGE_OPTIONS,
  EMR_OPTIONS,
  FACILITY_TYPE_OPTIONS,
  POLICY_OPTIONS,
  SERVICE_OPTIONS,
  URGENCY_OPTIONS,
} from '@/lib/facility/intake';
import { type FacilityIntakeState, submitFacilityIntake } from '@/server/actions/facilityIntake';
import { useActionState, useEffect, useId, useState } from 'react';

const TABS = [
  { key: 'facility', label: 'Facility' },
  { key: 'contacts', label: 'Key contacts' },
  { key: 'service', label: 'Service request' },
  { key: 'compliance', label: 'Compliance' },
  { key: 'billing', label: 'Billing & notes' },
] as const;
type TabKey = (typeof TABS)[number]['key'];

/** Map a validation-failed field (from the server) to the tab that contains it. */
const fieldToTab = (field: string | undefined): TabKey | null => {
  if (!field) return null;
  if (/^(administrator|don|mds1|mds2|itContact)/.test(field)) return 'contacts';
  if (
    /^(servicesRequested|emr|access|coverageType|weeklyHours|targetStartDate|urgency)/.test(field)
  )
    return 'service';
  if (/^(baaRequired|requiredPolicies|policyUploadLink)/.test(field)) return 'compliance';
  if (/^(invoiceRecipient|authorizedRep|additionalNotes)/.test(field)) return 'billing';
  return 'facility';
};

/** A labelled checkbox group whose options all submit under the same field name (read via getAll). */
function CheckGroup({
  legend,
  name,
  options,
}: {
  legend: string;
  name: string;
  options: readonly string[];
}) {
  return (
    <fieldset className="m-0 rounded-lg border border-slate-200 p-3">
      <legend className="px-1.5 text-sm font-semibold text-slate-700">{legend}</legend>
      <div className="grid gap-2">
        {options.map((o) => (
          <Checkbox key={o} name={name} value={o} label={o} />
        ))}
      </div>
    </fieldset>
  );
}

/**
 * Name / email / phone (+ optional title) for one named contact role. `required` only drops the
 * "(optional)" labels — there is no native `required` because tab panels are hidden, and a hidden
 * required control can't be focused for browser validation; the server enforces it instead.
 */
function ContactFields({
  legend,
  prefix,
  includeTitle,
  required,
}: {
  legend: string;
  prefix: string;
  includeTitle?: boolean;
  required?: boolean;
}) {
  const uid = useId();
  return (
    <fieldset className="m-0 grid gap-3 rounded-lg border border-slate-200 p-3">
      <legend className="px-1.5 text-sm font-semibold text-slate-700">
        {legend}
        {required ? <span className="ml-1 text-red-600">*</span> : null}
      </legend>
      <div className="grid gap-3 sm:grid-cols-2">
        <Field label="Name" htmlFor={`${uid}-name`} optional={!required}>
          <Input id={`${uid}-name`} name={`${prefix}Name`} maxLength={200} />
        </Field>
        {includeTitle ? (
          <Field label="Title" htmlFor={`${uid}-title`} optional>
            <Input id={`${uid}-title`} name={`${prefix}Title`} maxLength={200} />
          </Field>
        ) : null}
        <Field label="Email" htmlFor={`${uid}-email`} optional={!required}>
          <Input id={`${uid}-email`} name={`${prefix}Email`} type="email" maxLength={200} />
        </Field>
        <Field label="Phone" htmlFor={`${uid}-phone`} optional>
          <Input id={`${uid}-phone`} name={`${prefix}Phone`} maxLength={50} />
        </Field>
      </div>
    </fieldset>
  );
}

/**
 * Add-a-facility intake survey (the import-file fields). Organised into tabs to limit scrolling; all
 * panels stay mounted (hidden via the `hidden` utility) so every field submits in one go. On a
 * validation error the form jumps to the tab holding the offending field. Submitting creates/
 * re-activates the facility, stores the intake, seeds contacts, and redirects to the facility.
 */
export function FacilityIntakeForm() {
  const [state, action, pending] = useActionState(submitFacilityIntake, {
    ok: false,
  } as FacilityIntakeState);
  const uid = useId();
  const [tab, setTab] = useState<TabKey>('facility');

  useEffect(() => {
    const t = fieldToTab(state.field);
    if (state.error && t) setTab(t);
  }, [state]);

  const panel = (key: TabKey) => cn('gap-4', tab === key ? 'grid' : 'hidden');

  return (
    <form action={action} className="grid max-w-2xl gap-5">
      <div
        role="tablist"
        aria-label="Facility sections"
        className="flex flex-wrap gap-1 border-b border-slate-200"
      >
        {TABS.map((t) => (
          <button
            key={t.key}
            type="button"
            role="tab"
            id={`${uid}-tab-${t.key}`}
            aria-selected={tab === t.key}
            aria-controls={`${uid}-panel-${t.key}`}
            onClick={() => setTab(t.key)}
            className={cn(
              '-mb-px rounded-t-md border-b-2 px-3 py-2 text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-400',
              tab === t.key
                ? 'border-brand-500 text-brand-700'
                : 'border-transparent text-slate-500 hover:text-slate-800',
            )}
          >
            {t.label}
          </button>
        ))}
      </div>

      {state.error ? <Alert tone="danger">{state.error}</Alert> : null}

      <div
        role="tabpanel"
        id={`${uid}-panel-facility`}
        aria-labelledby={`${uid}-tab-facility`}
        className={panel('facility')}
      >
        <Field label="Facility legal name" htmlFor={`${uid}-legal`}>
          <Input id={`${uid}-legal`} name="legalName" maxLength={300} />
        </Field>
        <Field label="DBA / facility name (if different)" htmlFor={`${uid}-dba`} optional>
          <Input id={`${uid}-dba`} name="dbaName" maxLength={300} />
        </Field>
        <CheckGroup legend="Facility type" name="facilityTypes" options={FACILITY_TYPE_OPTIONS} />
        <Field label="Facility address" htmlFor={`${uid}-addr`} optional>
          <Input
            id={`${uid}-addr`}
            name="address"
            maxLength={500}
            placeholder="Street, City, ST ZIP"
          />
        </Field>
        <div className="grid gap-4 sm:grid-cols-2">
          <Field label="Facility phone" htmlFor={`${uid}-phone`} optional>
            <Input id={`${uid}-phone`} name="phone" maxLength={50} />
          </Field>
          <Field label="General email / main inbox" htmlFor={`${uid}-gemail`} optional>
            <Input id={`${uid}-gemail`} name="generalEmail" maxLength={200} />
          </Field>
        </div>
        <Field label="Preferred communication method" htmlFor={`${uid}-comms`} optional>
          <Select id={`${uid}-comms`} name="preferredComms" defaultValue="">
            <option value="">—</option>
            <option value="Email">Email</option>
            <option value="Phone">Phone</option>
            <option value="Text/SMS">Text/SMS</option>
            <option value="Portal">Portal</option>
          </Select>
        </Field>
      </div>

      <div
        role="tabpanel"
        id={`${uid}-panel-contacts`}
        aria-labelledby={`${uid}-tab-contacts`}
        className={panel('contacts')}
      >
        <ContactFields legend="Administrator" prefix="administrator" />
        <ContactFields legend="Director of Nursing (DON)" prefix="don" />
        <ContactFields legend="MDS Coordinator #1" prefix="mds1" />
        <ContactFields legend="MDS Coordinator #2" prefix="mds2" />
        <ContactFields legend="IT / EMR contact" prefix="itContact" />
      </div>

      <div
        role="tabpanel"
        id={`${uid}-panel-service`}
        aria-labelledby={`${uid}-tab-service`}
        className={panel('service')}
      >
        <CheckGroup
          legend="Which services are you requesting?"
          name="servicesRequested"
          options={SERVICE_OPTIONS}
        />
        <Field label="Which EMR does your facility use?" htmlFor={`${uid}-emr`} optional>
          <Select id={`${uid}-emr`} name="emr" defaultValue="">
            <option value="">—</option>
            {EMR_OPTIONS.map((o) => (
              <option key={o} value={o}>
                {o}
              </option>
            ))}
          </Select>
        </Field>
        <CheckGroup
          legend="Access requirements"
          name="accessRequirements"
          options={ACCESS_OPTIONS}
        />
        <Field label="Special instructions for access" htmlFor={`${uid}-access`} optional>
          <Textarea
            id={`${uid}-access`}
            name="accessInstructions"
            rows={2}
            maxLength={2000}
            className="resize-y"
          />
        </Field>
        <div className="grid gap-4 sm:grid-cols-2">
          <Field label="Coverage needed" htmlFor={`${uid}-coverage`} optional>
            <Select id={`${uid}-coverage`} name="coverageType" defaultValue="">
              <option value="">—</option>
              {COVERAGE_OPTIONS.map((o) => (
                <option key={o} value={o}>
                  {o}
                </option>
              ))}
            </Select>
          </Field>
          <Field label="Expected weekly hours" htmlFor={`${uid}-hours`} optional>
            <Input
              id={`${uid}-hours`}
              name="weeklyHours"
              maxLength={120}
              placeholder="30–40 hours"
            />
          </Field>
          <Field label="Target start date" htmlFor={`${uid}-start`} optional>
            <Input id={`${uid}-start`} name="targetStartDate" type="date" />
          </Field>
          <Field label="Urgency level" htmlFor={`${uid}-urgency`} optional>
            <Select id={`${uid}-urgency`} name="urgency" defaultValue="">
              <option value="">—</option>
              {URGENCY_OPTIONS.map((o) => (
                <option key={o} value={o}>
                  {o}
                </option>
              ))}
            </Select>
          </Field>
        </div>
      </div>

      <div
        role="tabpanel"
        id={`${uid}-panel-compliance`}
        aria-labelledby={`${uid}-tab-compliance`}
        className={panel('compliance')}
      >
        <Field
          label="Does your facility require a Business Associate Agreement (BAA)?"
          htmlFor={`${uid}-baa`}
          optional
        >
          <Select id={`${uid}-baa`} name="baaRequired" defaultValue="">
            <option value="">—</option>
            <option value="Yes">Yes</option>
            <option value="No">No</option>
            <option value="Already on file">Already on file</option>
          </Select>
        </Field>
        <CheckGroup legend="Required policies" name="requiredPolicies" options={POLICY_OPTIONS} />
        <Field label="Policy upload link" htmlFor={`${uid}-policylink`} optional>
          <Input id={`${uid}-policylink`} name="policyUploadLink" maxLength={500} />
        </Field>
      </div>

      <div
        role="tabpanel"
        id={`${uid}-panel-billing`}
        aria-labelledby={`${uid}-tab-billing`}
        className={panel('billing')}
      >
        <ContactFields legend="Invoice recipient" prefix="invoiceRecipient" required />
        <ContactFields
          legend="Authorized representative"
          prefix="authorizedRep"
          includeTitle
          required
        />
        <Field label="Additional requests / notes" htmlFor={`${uid}-notes`} optional>
          <Textarea
            id={`${uid}-notes`}
            name="additionalNotes"
            rows={4}
            maxLength={8000}
            className="resize-y"
            placeholder="Special requests, constraints, scheduling context…"
          />
        </Field>
      </div>

      <div className="flex flex-wrap items-center gap-3">
        <Button type="submit" loading={pending} disabled={pending}>
          {pending ? 'Saving…' : 'Add facility'}
        </Button>
        <span className="text-xs text-slate-500">
          Required: facility legal name, invoice recipient, authorized representative.
        </span>
      </div>
    </form>
  );
}
