'use client';

import {useState} from 'react';
import {VStack, HStack} from '@astryxdesign/core/Layout';
import {FormLayout} from '@astryxdesign/core/FormLayout';
import {TextInput} from '@astryxdesign/core/TextInput';
import {NumberInput} from '@astryxdesign/core/NumberInput';
import {Button} from '@astryxdesign/core/Button';
import {Text} from '@astryxdesign/core/Text';
import {Divider} from '@astryxdesign/core/Divider';
import {useToast} from '@astryxdesign/core/Toast';
import {StaticPanel} from '@/shared/components/patterns/PanelCard';
import {settingsService} from '@/features/settings/services/settingsService';
import type {ProfileFieldErrors} from '@/features/settings/services/settingsService';
import type {MerchantProfile} from '@/features/settings/types/settings';

/**
 * Merchant profile.
 *
 * `initialData` arrives from a Server Component that read the record
 * DIRECTLY — no HTTP round trip — so the form paints filled on first render
 * rather than flashing empty inputs. This is the hybrid path the data layer
 * was designed for: dashboards fetch on the client because their scope
 * changes constantly, but a settings form has exactly one server-known state
 * at page load and should use it.
 *
 * Status is only ever set on submit, never at initial paint — Astryx's
 * FieldStatus breaks SSR hydration when it is server-rendered with a status
 * already applied (see AGENTS.md).
 */
export function ProfileForm({initialData}: {initialData: MerchantProfile}) {
  const toast = useToast();
  const [form, setForm] = useState(initialData);
  const [isSaving, setIsSaving] = useState(false);
  const [errors, setErrors] = useState<ProfileFieldErrors>({});

  const set = <K extends keyof MerchantProfile>(
    key: K,
    value: MerchantProfile[K],
  ) => setForm((f) => ({...f, [key]: value}));

  const isDirty = JSON.stringify(form) !== JSON.stringify(initialData);

  async function save() {
    // Validation and transport both live in settingsService — this component
    // decides what to render, never what a valid profile is or where it goes.
    // The raw fetch that used to sit here was the last one in the codebase.
    setIsSaving(true);
    const result = await settingsService.saveProfile(form);
    setIsSaving(false);

    if (result.ok) {
      setErrors({});
      toast({body: 'Profile saved'});
      return;
    }
    setErrors(result.errors);
    if (result.message) {
      toast({type: 'error', body: result.message});
    }
  }

  return (
    <StaticPanel
      title="Business profile"
      subtitle="Shown on receipts and used for LYT settlement."
      actions={
        <HStack gap={2} vAlign="center">
          {isDirty ? (
            <Text size="sm" color="secondary">
              Unsaved changes
            </Text>
          ) : null}
          <Button
            variant="secondary"
            size="sm"
            label="Reset"
            isDisabled={!isDirty || isSaving}
            onClick={() => {
              setForm(initialData);
              setErrors({});
            }}
          />
          <Button
            variant="primary"
            size="sm"
            label="Save changes"
            isDisabled={!isDirty}
            isLoading={isSaving}
            onClick={save}
          />
        </HStack>
      }
    >
      <VStack gap={5}>
        <FormLayout direction="horizontal">
          <TextInput
            label="Business name"
            value={form.businessName}
            onChange={(v) => set('businessName', v)}
            isRequired
            status={
              errors.businessName
                ? {type: 'error', message: errors.businessName}
                : undefined
            }
          />
          <TextInput
            label="Contact name"
            value={form.contactName}
            onChange={(v) => set('contactName', v)}
          />
        </FormLayout>

        <FormLayout direction="horizontal">
          <TextInput
            label="Email"
            type="email"
            value={form.email}
            onChange={(v) => set('email', v)}
            isRequired
            status={
              errors.email ? {type: 'error', message: errors.email} : undefined
            }
          />
          <TextInput
            label="Phone"
            value={form.phone}
            onChange={(v) => set('phone', v)}
          />
        </FormLayout>

        <Divider />

        <FormLayout direction="horizontal">
          <TextInput
            label="GSTIN"
            value={form.gstin}
            onChange={(v) => set('gstin', v.toUpperCase())}
            description="15-character GST registration number"
            status={
              errors.gstin ? {type: 'error', message: errors.gstin} : undefined
            }
          />
          <TextInput
            label="Timezone"
            value={form.timezone}
            onChange={(v) => set('timezone', v)}
            description="All reports are rendered in this zone"
          />
        </FormLayout>

        <NumberInput
          label="LYTs per ₹100 spent"
          value={form.lytsPerHundred}
          onChange={(v) => set('lytsPerHundred', v ?? 0)}
          min={0}
          max={100}
          description="1 LYT = ₹1. At 5, a ₹1,000 basket earns 50 LYTs — ₹50 of future liability."
          width={320}
        />
      </VStack>
    </StaticPanel>
  );
}
